为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

翻过高山走不出你 2021-11-23 19:19:55
有没有办法将相同的属性逻辑应用于类中的一组属性?例如,我想申请相同的@attr1.setter装饰器attr2,attr3以及attr4不必定义每个属性的属性。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
查看完整描述

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 的变量。使用双下划线名称修改会使这里的事情复杂化。


查看完整回答
反对 回复 2021-11-23
?
温温酱

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


查看完整回答
反对 回复 2021-11-23
  • 2 回答
  • 0 关注
  • 191 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号