我正试图创建一个值为false的SimpleNamespace,但它对我不起作用。
EMPTY = types.SimpleNamespace(__bool__=lambda self: False)
assert bool(EMPTY) == False # raises error!!
有没有一种方法可以创建布尔值为false的SimpleNamespace?
不可能提供自定义,"真实的";方法到类的各个实例。在原始代码中,EMPTY.__bool__
不是一个方法,而是一个普通函数。您可以通过尝试显式调用它来看到这一点:
>>> EMPTY = types.SimpleNamespace(__bool__=lambda self: False)
>>> EMPTY.__bool__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: <lambda>() missing 1 required positional argument: 'self'
请参见将方法添加到现有对象实例。虽然有可能——遵循那里的建议——让EMPTY.__bool__
表现得像一种方法:
>>> EMPTY = types.SimpleNamespace()
>>> EMPTY.__bool__ = types.MethodType(lambda self: False, EMPTY)
>>> EMPTY.__bool__()
False
仍将被bool
:忽略
>>> bool(EMPTY)
True
bool
的实现直接在类上查找__bool__
,因为它没有理由期望实例具有这样的属性。
相反,我们需要有自己的类,使用名为__bool__
的实际方法来做正确的事情。因此:
class PossiblyEmptyNamespace(types.SimpleNamespace):
"""A namespace that is falsey when it doesn't contain anything."""
def __bool__(self):
return bool(vars(self))
现在我们可以测试:
>>> EMPTY = PossiblyEmptyNamespace()
>>> bool(EMPTY)
False
>>> EMPTY.foo = 'bar'
>>> bool(EMPTY) # oops, not actually empty any more.
True
如注释中所述,您需要创建一个子类。像__bool__
这样的Dunder方法通常在类中查找,而不是在特定的实例中查找,所以在实例中设置字段对这种情况没有好处。
from types import SimpleNamespace
class FalsyNamespace(SimpleNamespace):
def __bool__(self):
return False
EMPTY = FalsyNamespace()
assert bool(EMPTY) == False