2 回答

TA貢獻1936條經驗 獲得超7個贊
你需要一個@property
:
class Dummy:
? ? def __init__(self, x):
? ? ? ? self.x = x
? ? @property
? ? def x(self):
? ? ? ? return self._x
? ? @x.setter
? ? def x(self, value):
? ? ? ? if value is None:
? ? ? ? ? ? raise Exception("x cannot be None")
? ? ? ? self._x = value
d = Dummy(8)
d.x = 16
d.x = None? # Raises

TA貢獻1833條經驗 獲得超4個贊
注意:我將此處的問題解釋為防止將所有屬性設置為None之外的意思__init__,盡管在下面添加了一個選項來保護某些指定的屬性。
這個怎么樣?有__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,那么這是可以規避的,但是他們應該知道他們正在做一些不受支持的事情。
添加回答
舉報