2011-08-29 28 views
1

我寫了一個類人用元類法術。在元類中,我改變了一個屬性,這是可以的,但是如果我想爲另一個操作使用這個新的值,它不起作用,它使用以前的值。 我該如何解決這個問題?蟒蛇元類不記得了新的價值

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,爲什麼呢?錯誤在哪裏?

+0

你需要修復您的壓痕 –

+1

什麼是你要使用元類的原因嗎?在你的例子中,沒有什麼東西比普通的基類更容易。 –

+0

我不得不使用元類爲大學的考試,這是在準備考試 – fege

回答

2

你建立的lambda是指一流的施工過程中充滿了字典。後來(類創建後)改變類變量沒有反映在它,但即使是這樣的話,行persona4.pay_per_hour = 15分配一個新的實例,而不是屬性更改類屬性。在pph生成的函數中使用self.pay_per_hour來獲取當前正在討論的實例使用的值。

,或者甚至更好,廢除元類。沒有理由在這裏使用它們,正如你所看到的,很容易讓事情的可擴展性比需要的小。

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的更改。

+0

此練習。我不確定在這種情況下使用元類的好處是什麼。看起來好的,老式的階級繼承應該是綽綽有餘的。 – 2011-08-29 10:17:29

1

的問題是,你的函數pph只能仰望的pay_per_hour值在類字典,當你只覆蓋的pay_per_hour在實例中的價值。在Python中,查找對象字段的值時,首先檢查實例字典,然後檢查類字典(以及所有超級類的mro順序)。

你需要你的元類更改爲:

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) 
+0

完美,謝謝 – fege