Python-相同的属性逻辑可以应用于多个属性吗?

Python-相同的属性逻辑可以应用于多个属性吗?,python,python-3.x,properties,decorator,Python,Python 3.x,Properties,Decorator,有没有办法将相同的属性逻辑应用于类中的一组属性?例如,我想对attr2、attr3和attr4应用相同的@attr1.setter装饰器,而不必为每个属性定义属性 class Sample: def __init__(self): self.attr1 = None self.attr2 = None self.attr3 = None self.attr4 = None @property def att

有没有办法将相同的属性逻辑应用于类中的一组属性?例如,我想对
attr2
attr3
attr4
应用相同的
@attr1.setter
装饰器,而不必为每个属性定义属性

class Sample:
    def __init__(self):
        self.attr1 = None
        self.attr2 = None
        self.attr3 = None
        self.attr4 = None

    @property
    def attr1(self):
        return self.__attr1

    @attr1.setter
    def attr1(self, val):
        if val < 0:
            self.__attr1 = 0
        else:
            self.__attr1 = val
类示例:
定义初始化(自):
self.attr1=无
self.attr2=无
self.attr3=无
self.attr4=无
@财产
def属性1(自身):
返回自我。\u属性1
@属性1.setter
def属性1(自身,val):
如果val<0:
自身属性1=0
其他:
self.\uu attr1=val

只需为此创建您自己的描述符:

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
请参阅和一些更相关的


注意,我在setter逻辑中加入了
None
的可能性(您的代码在初始化实例时会引发
TypeError
,因为setter检查
None<0
)。还要注意的是,您可能不想使用双下划线名称混乱(,它并不意味着private),因此我使用了传统的单下划线来表示不属于公共api的变量。在这里使用双下划线名称会使事情变得复杂。

您可以覆盖
\uuuu getattr\uuuuu
\uuuu setattr\uuuu
以按照您希望的方式进行操作。这样,您不需要定义任何私有变量,也不需要初始化任何成员变量

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
类示例:
def _ugetattr _;(self,attr):
返回self.\u dict\u.get(attr)
定义设置属性(self、attr、val):
如果val不是None且val<0:
self.\uuuu dict\uuuu[attr]=0
其他:
self.\uu dict\uu[attr]=val
s=样本()
打印(s.attr1)#无
s、 属性1=10
印刷品(s.1)#10
s、 属性1=-10
印刷品(s.attr1)#0
s、 属性1=无
打印(s.attr1)#无

如果我将attr1/2/3/4定义为类属性,它们不会在类实例之间共享吗?i、 e.
attr1=MyDescriptor()
@tylex这正是
属性所做的。也就是说,属性对象属于该类。所以
@property def blah()…
相当于
def blah()。。。blah=属性(blah)
。描述符(属性
只是一个方便的描述符)总是属于类。
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