python 元类不记得新值
我用元类 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,为什么?错误在哪里?
I wrote a class Person with a metaclass Spell. 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? where is the error?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您创建的 lambda 指的是在类构造期间填充的字典。稍后(在类创建之后)对类变量的更改不会反映在其中,但即使是这种情况,行
persona4.pay_per_hour = 15
也会分配一个新的实例属性,而不是更改类属性。在pph
生成的函数中使用self.pay_per_hour
来获取相关实例当前使用的值。或者,更好的是,取消元类。没有理由在这里使用它们,正如您所看到的,很容易使事情的可扩展性低于所需的程度。
这会在实例级别透明地处理 pay_per_hour 和 hours_per_day 的更改。
The lambda you created refers to the dictionary filled during class construction. 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. Useself.pay_per_hour
in the functions produced bypph
to get the value the instance in question uses at the moment.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.
This handles changes to pay_per_hour and hours_per_day transparently and at instance level.
问题在于,您的函数
pph
仅在类字典中查找pay_per_hour
的值,而您仅覆盖了类字典中pay_per_hour
的值。实例。在Python中,当你查找一个对象的字段值时,它首先检查实例字典,然后检查类字典(以及mro顺序中的所有超类)。您需要将元类更改为:
The problem is that your function
pph
only look up the value ofpay_per_hour
in the class dictionary, while you only override the value ofpay_per_hour
in the instance. 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).You need to change your metaclass to: