以下python代码有一个错误:
class Location(object):
def is_nighttime():
return ...
if location.is_nighttime:
close_shades()
错误是程序员忘记调用is_nighttime
(或忘记在方法上使用@property
装饰器),因此该方法是bool
在没有被调用的情况下评估为True
。
在上面的情况下,以及在is_nighttime
是独立函数而不是方法的情况下,有没有办法阻止程序员这样做?例如,具有以下精神的东西?
is_nighttime.__bool__ = TypeError
答案 0 :(得分:10)
理论上,您可以将函数包装在类似函数的对象中,其中__call__
委托给函数,__bool__
引发TypeError。它真的很笨拙,并且可能会导致更多的错误交互而不是它捕获 - 例如,除非你为此添加更多特殊处理,否则这些对象将无法用作方法 - 但你可以这样做:
class NonBooleanFunction(object):
"""A function wrapper that prevents a function from being interpreted as a boolean."""
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
return self.func(*args, **kwargs)
def __bool__(self):
raise TypeError
__nonzero__ = __bool__
@NonBooleanFunction
def is_nighttime():
return True # We're at the Sun-Earth L2 point or something.
if is_nighttime:
# TypeError!
还有很多你无法捕捉到的东西:
nighttime_list.append(is_nighttime) # No TypeError ._.
你必须记住明确地将它应用于你不希望被视为布尔值的任何函数。你也无法做很多关于你无法控制的功能和方法;例如,您无法将此应用于str.islower
以捕获if some_string.islower:
等内容。
如果你想抓住这样的东西,我推荐使用静态分析工具。我认为像PyCharm这样的IDE可能会警告你,并且应该有可以捕获它的linting工具。
如果你想让这些东西作为方法工作,这里有额外的处理:
import functools
class NonBooleanFunction(object):
... # other methods omitted for brevity
def __get__(self, instance, owner):
if instance is None:
return self
return NonBooleanFunction(functools.partial(self.func, instance))
答案 1 :(得分:8)
这是您可以通过静态代码分析来实现的。
例如,pylint
有一个related warning:
using-constant-test (W0125):
使用条件语句 常量值在条件语句时发出(如果是或者是三元组) 使用常量值进行测试。这可能不是用户 打算做。
演示:
如果未调用is_nightmare
:
$ pylint test.py
************* Module test
C: 1, 0: Missing module docstring (missing-docstring)
C: 1, 0: Missing function docstring (missing-docstring)
W: 4, 0: Using a conditional statement with a constant value (using-constant-test)
如果被召唤:
$ pylint test.py
************* Module test
C: 1, 0: Missing module docstring (missing-docstring)
C: 1, 0: Missing function docstring (missing-docstring)
答案 2 :(得分:-2)
简答:if is_nighttime():
,用括号表示。
更长的答案:
is_nighttime
指向一个非None类型的函数。 if
查找一个布尔条件,并将符号is_nighttime
强制转换为布尔值。因为它不是零而不是无,它是真的。