【问题标题】:Perform method when an attribute is added to a class in Python在Python中将属性添加到类时执行方法
【发布时间】:2015-01-08 20:45:50
【问题描述】:

我想实例化一个类,比如Fighter,有和没有属性weapon_size。但是当属性weapon_size 设置时(在实例化时或以后)我想运行一些添加另一个属性damage 的方法(并且可能进行一些其他计算)。我试图通过重载 setattr 函数来做到这一点,如下所示。

我的问题:这是正确的 [和明智的] 方法吗?

class Fighter(object):
    def __init__(self, prenom, weapon_size = None):
        self._prenom = prenom
        self._weapon_size = weapon_size
        if not weapon_size is None:
            self.AddWeapon(weapon_size)

    def __setattr__(self, name, value):
            if name == "weapon_size":
                print "Adding weapon"
                self.AddWeapon(value)
                self.__dict__['_' + name] = value
            else:
                self.__dict__[name] = value

    def AddWeapon(self, x):
        self._damage = x/2.

    @property
    def weapon_size(self):
        "Weapon size"
        return self._weapon_size
    @property
    def prenom(self):
        "First name"
        return self._prenom

U = Fighter('Greg')
U.weapon_size = 9
print U.weapon_size, U._damage
>> 9 4.5
W = Fighter('Jeff', weapon_size = 11)
print W.weapon_size, W._damage
>> 11 5.5

【问题讨论】:

    标签: python class python-2.7 methods setattr


    【解决方案1】:

    您可以为特定属性定义自定义设置器。

    @weapon_size.setter
    def weapon_size(self, value):
        # custom code here
        self._weapon_size = value
    

    编辑:但实际上,归根结底,我认为您只需这样做会更清洁:

    class Fighter(object):
        def __init__(self, prenom, weapon_size=None):
            ...
            self.weapon_size = weapon_size
            ...
    
        @property
        def damage(self):
            if self.weapon_size:
                return self.weapon_size / 2
            return None
    

    【讨论】:

    • 完美,谢谢。请问,使用 setattr 有什么缺点?我处理不该处理的案件?
    • 因为属性基本上是为您要解决的确切问题创建的。如果可能,应始终避免覆盖任何 __x__ 方法。使用__setattr__,您可以修改为所有属性调用的方法,而您只关心weapon_size。这种方式更精确。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多