如何防止函数被强制转换为bool

时间:2016-05-19 22:24:16

标签: python

以下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

3 个答案:

答案 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强制转换为布尔值。因为它不是零而不是无,它是真的。