2 回答
TA贡献1785条经验 获得超4个赞
只需为此创建您自己的描述符:
class MyDescriptor:
def __set_name__(self, owner, name):
self.name = f'_{name}'
def __get__(self, instance, owner):
return getattr(instance, self.name)
def __set__(self, instance, val):
if val is None:
setattr(instance, self.name, None)
elif val < 0:
setattr(instance, self.name, 0)
else:
setattr(instance, self.name, val)
class Sample:
attr1 = MyDescriptor()
attr2 = MyDescriptor()
attr3 = MyDescriptor()
attr4 = MyDescriptor()
def __init__(self):
self.attr1 = None
self.attr2 = None
self.attr3 = None
self.attr4 = None
现在,在行动:
In [3]: s = Sample()
In [4]: s.attr1 = -99
In [5]: s.attr1
Out[5]: 0
In [6]: s.attr2
In [7]: s.attr2 = 10
In [8]: s.attr2
Out[8]: 10
In [9]: s.attr2 = -1
In [10]: s.attr2
Out[10]: 0
请参阅描述符 HOWTO和一些更相关的文档
请注意,我None在您的 setter 逻辑中加入了可能性(您的代码会TypeError在实例初始化时引发 a ,因为 setter 检查 if None < 0)。另请注意,您可能不想使用双下划线名称修饰(这并不意味着 private),因此我使用传统的单下划线来表示不属于公共 api 的变量。使用双下划线名称修改会使这里的事情复杂化。
TA贡献1752条经验 获得超4个赞
您可以覆盖__getattr__和__setattr__以按照您希望的方式行事。这样你就不需要定义任何私有变量,也不需要初始化任何成员变量。
class Sample:
def __getattr__(self, attr):
return self.__dict__.get(attr)
def __setattr__(self, attr, val):
if val is not None and val < 0:
self.__dict__[attr] = 0
else:
self.__dict__[attr] = val
s = Sample()
print(s.attr1) # None
s.attr1 = 10
print(s.attr1) # 10
s.attr1 = -10
print(s.attr1) # 0
s.attr1 = None
print(s.attr1) # None
添加回答
举报
