4
>>> def mod2(n):
...   print 'the remainder is', n % 2
... 
>>> mod2(5)
the remainder is 1
>>> mod2(2)
the remainder is 0
>>> mod2('%d')
the remainder is 2
>>> mod2('%d\rHELLO. I AM A POTATO!')
HELLO. I AM A POTATO!

とにかく、%symbol(operator.mod)が奇抜な文字列置換を行うのを無効にする方法はありますか?私はそのようなものが必要な場合は常に使用しますstr.formatが、通常、この文字列置換機能はまったく存在せず、TypeError代わりに使用します。

4

6 に答える 6

4

それが数値であることを確認したい場合n、最も簡単な方法は、事前に数値演算を実行することです。

def mod2(n):
    n - 1
    print 'the remainder is', n % 2

これによりTypeError、文字列から削除することはできませんが、すべての数値タイプから削除することはできないため、が確実に発生します。

これをtry/catchブロックで囲み、実際の問題をもう少し説明する独自の例外を発生させることができます。

別の注意点として、データの種類の保存にはもっと注意する価値があるかもしれません。Pythonはダックタイピングされていますが、数値や文字列を渡すことができる状況になるのは少し奇妙です。文字列を正しく処理しないというメモは正しい呼び出しかもしれません。

于 2012-12-11T11:49:38.203 に答える
4

いいえ、スイッチで無効にすることはできません。このstr()型は、書式設定を処理する__mod__メソッドを実装します。Pythonが文字列専用の式を特殊に指定したわけではありません。

nそのため、これを防ぐには、引数を文字列ではないものにキャストするか(int()たとえば、に変換して)、サブクラスを使用してメソッドstr()をオーバーライドする必要があります。__mod__

>>> class noformattingstr(str):
...     def __mod__(self, other):
...         raise TypeError('String formatting using "%" has been deprecated')
... 
>>> noformattingstr('hello world: %d') % 10
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __mod__
TypeError: String formatting using "%" has been deprecated

これをに割り当てることができますが、これは、すべての文字列リテラルがサブクラスを使用することを意味するわけで__builtins__.strはありません。str()代わりに、値をnoformattingstr()インスタンスに明示的にキャストする必要があります。

于 2012-12-11T11:50:07.417 に答える
0
def mod2(n):
    print('the remainder is %d' % (n % 2))

mod2(5)
# the remainder is 1
mod2('%d\rHELLO. I AM A POTATO!')
# TypeError: %d format: a number is required, not str
于 2012-12-11T11:39:18.883 に答える
0

関数内でint()を使用してnをキャストします。

def mod2(n):
    print 'the remainder is', int(n) % 2
于 2012-12-11T11:42:59.883 に答える
0

なぜeumiroが彼の答えを削除したのかはわかりませんが、それも私が提案したことです。サポートされていない型について明示的に型をチェックして、モジュロ演算子を実際にサポートする型(floatなど)に対して開いたままにすることを除いて、次のようにします。

def mod2(n):
    if isinstance(n, basestring): # for Py3 use `isinstance(n, str)`
        raise TypeError('unsupported type')
    else:
        print 'the remainder is', n % 2
于 2012-12-11T11:49:45.467 に答える
0

たとえできたとしても、あなたはしたくないでしょう。そこにある膨大な量のコード%は、Pythonライブラリのコードを含め、文字列のフォーマット方法をまだ使用しています。

演算子はオペコード%にコンパイルされます。BINARY_MODULO

>>> dis.dis(mod2)
  2           0 LOAD_CONST               1 ('the remainder is')
              3 PRINT_ITEM          
              4 LOAD_FAST                0 (n)
              7 LOAD_CONST               2 (2)
             10 BINARY_MODULO       
             11 PRINT_ITEM          
             12 PRINT_NEWLINE       
             13 LOAD_CONST               0 (None)
             16 RETURN_VALUE        

つまり、パラメータを変更せずに文字列のフォーマットが発生するのを防ぐ方法はありません。また、コードで任意の数値型を使用できるようにする場合は、それらが独自の方法で、つまり演算子を使用してモジュロ演算を処理できるようにする必要があります%

引数が数値型であることを確認するには、次を使用しますnumbers

from number import Number
if not isinstance(n, Number):
    raise TypeError(n)
于 2012-12-11T11:53:02.287 に答える