我写了一个具有Metaclass Spell的Person类。在元类中,我更改了一个属性,并且可以,但是,如果我想将此新值用于其他操作,则该行将不起作用,并且将使用先前的值。
我怎样才能解决这个问题?
class Spell(type):
def __new__(cls,classname,super,classdict):
def pph( hours ): return lambda self : classdict['pay_per_hour'] * hours
classdict['pay_per_hour'] = 12
classdict['day_salary'] = pph(8)
return type.__new__(cls, classname, super, classdict )
class Person(metaclass=Spell):
def __init__(self,name,lastname,bday):
self.name = name
self.lastname = lastname
self.bday = bday
def get_name(self):
return self._name
def get_lastname(self):
return self._lastname
def get_bday(self):
return self._bday
def __repr__(self):
return "name: {0}, lastname: {1}, bday: {2}".format(self.name,self.lastname,self.bday)
if __name__ == "__main__":
persona4 = Person("lugdfgca","djfosd","16 febbraio 85")
print(persona4.pay_per_hour)
print(persona4.day_salary())
persona4.pay_per_hour=15
print(persona4.pay_per_hour)
print(persona4.day_salary())
输出是
12
96
15
96
但是96是12 * 8而不是15 * 8,为什么?错误在哪里?
最佳答案
您创建的lambda指的是在类构建期间填充的字典。稍后(在创建类之后)对类变量的更改不会反映在其中,但是即使是这种情况,行persona4.pay_per_hour = 15
也会分配新的实例属性,而不是更改类属性。在self.pay_per_hour
产生的函数中使用pph
来获取实例正在使用的值。
或者,甚至更好的是,不要使用元类。没有理由在这里使用它们,正如您所看到的,很容易使事情的扩展性超出所需。
class Spell:
pay_per_hour = 12
hours_per_day = 8
# @property # allows nicer syntax, look it up if you don't know it
def day_salary(self):
return hours_per_day * pay_per_hour
class Person(Spell):
...
这将透明地在实例级别处理pay_per_hour和hours_per_day的更改。
关于python - python metaclass不记得新值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7228676/