[英]python metaclass doesn't remember the new value
I wrote a class Person with a metaclass Spell. 我写了一个具有Metaclass Spell的Person类。 In the metaclass I change an attribute and it is ok, but if i want to use this new value for another operation, it doesn't work and it use the previous value.
在元类中,我可以更改属性,并且可以,但是如果我想将此新值用于其他操作,则该行将不起作用,并且将使用先前的值。 How can i fix this?
我怎样才能解决这个问题?
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())
The output is 输出是
12
96
15
96
but 96 is 12*8 not 15*8, why? 但是96是12 * 8而不是15 * 8,为什么? where is the error?
错误在哪里?
The lambda you created refers to the dictionary filled during class construction. 您创建的lambda指的是在类构建期间填充的字典。 Later (after class creation) changes to class variables are not reflected in it, but even if that was the case, the line
persona4.pay_per_hour = 15
assigns a new instance attribute instead of changing the class attribute. 稍后(在创建类之后)对类变量的更改不会反映在其中,但是即使是这种情况,
persona4.pay_per_hour = 15
行persona4.pay_per_hour = 15
分配一个新的实例属性,而不是更改类属性。 Use self.pay_per_hour
in the functions produced by pph
to get the value the instance in question uses at the moment. 在
pph
产生的函数中使用self.pay_per_hour
获取有关实例当前使用的值。
Or, even better, do away with the metaclass. 或者,甚至更好的是,不要使用元类。 There's no reason to use them here, and as you saw, it's easy to make things less extensible than needed.
没有理由在这里使用它们,正如您所看到的,很容易使事情的扩展性超出所需。
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):
...
This handles changes to pay_per_hour and hours_per_day transparently and at instance level. 这将透明地在实例级别处理pay_per_hour和hours_per_day的更改。
The problem is that your function pph
only look up the value of pay_per_hour
in the class dictionary, while you only override the value of pay_per_hour
in the instance. 问题是,你的函数
pph
只能仰望的价值pay_per_hour
在类字典,当你只覆盖的值pay_per_hour
的实例。 In Python, when you lookup a value of a field of an object, it first check in the instance dictionary, then in the class dictionary (and all the super class in the mro order). 在Python中,当您查找对象字段的值时,它将首先检入实例字典,然后检入类字典(以及所有按mro顺序排列的超类)。
You need to change your metaclass to: 您需要将元类更改为:
def __new__(cls,classname,super,classdict):
def pph( hours ): return lambda self : self.pay_per_hour * hours
classdict['pay_per_hour'] = 12
classdict['day_salary'] = pph(8)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.