>>> 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!
无论如何禁止%
符号(operator.mod
)进行古怪的字符串替换?如果我需要这样的话,我总是使用str.format
,而且通常不会存在这个字符串替换功能,而是提供TypeError
。
答案 0 :(得分:4)
如果你想确保n
是一个数字,我认为最简单的方法是事先用它来执行数字运算:
def mod2(n):
n - 1
print 'the remainder is', n % 2
这样可以确保TypeError
会被提升,因为您无法从字符串中删除,而您可以使用所有数字类型。
您可能希望在try / catch块中包围它并引发您自己的异常,这可以更好地描述实际问题。
另外请注意,存储您的数据类型可能更值得注意。虽然Python是鸭子类型,但是有一个数字或字符串可以传入的情况有点奇怪。说明它不能正确处理字符串的说明可能是正确的调用。
答案 1 :(得分:4)
你不能用开关禁用它,没有。 str()
类型实现了一个__mod__
method来处理格式化,而不是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()
个实例。
答案 2 :(得分: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
答案 3 :(得分:0)
在函数中使用int()转换n。
def mod2(n):
print 'the remainder is', int(n) % 2
答案 4 :(得分:0)
我不知道为什么eumiro取消了他的答案,但这也是我所建议的。除了我会明确检查不支持类型的类型,以便为实际支持模运算符的类型(如浮点数)保持打开状态:
def mod2(n):
if isinstance(n, basestring): # for Py3 use `isinstance(n, str)`
raise TypeError('unsupported type')
else:
print 'the remainder is', n % 2
答案 5 :(得分: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)