注意:我将这里的问题解释为防止 所有 属性在 __init__ 之外设置为 None,尽管在下面添加了一个选项来保护某些指定的属性。
这个怎么样?将__setattr__ 方法作为object.__setattr__ 的包装器。
class Dummy:
def __init__(self, x):
self._None_forbidden = False
self.z = None # this will work
self._None_forbidden = True
def __setattr__(self, k, v):
if v is None and self._None_forbidden:
raise ValueError("cannot set attribute to None")
object.__setattr__(self, k, v)
d = Dummy("foo")
print(d.z) # None
d.y = 2
print(d.y) # 2
d.x = None # raises ValueError
如果您只是想保护某些属性,您可以将self._None_forbidden 设置为一组不允许设置为 None 的属性名称。例如:
class Dummy:
def __init__(self, x):
self._None_forbidden = set()
self.z = None # this will work
self._None_forbidden.add("z")
def __setattr__(self, k, v):
if v is None and k in self._None_forbidden:
raise ValueError("cannot set attribute to None")
object.__setattr__(self, k, v)
d = Dummy("foo")
print(d.z) # None
d.y = 2
print(d.y) # 2
d.x = None
print(d.x) # None
d.z = 4
print(d.z) # 4
d.z = None # raises ValueError
显然,如果调用者操纵了_None_forbidden,那么这可以被规避,但他们应该知道他们正在做一些不受支持的事情。