3

個人クラスと個人クラスに委譲する Manager クラスで構成される次のコードがあります。私はnew style object(から派生したobject)を使用しており、python 2.7を実行しています。理解できない最大の再帰深度を取得します。setattrを使用すると問題が発生することはわかっています(これをマネージャー クラスでコメントアウトすると、問題なく動作することがわかります)。この再帰が発生する理由とそれを回避する方法。

class Person(object):
    def __init__(self,name,job=None, pay=0):
        self.name=name
        self.job=job
        self.pay=pay

    def lastName(self):
        return self.name.split()[-1]

    def giveraise(self,percent):
        self.pay=int(self.pay*(1+percent))

    def __str__(self):
        return '[Person: %s, %s]' %(self.name, self.pay)


class Manager(object):
    def __init__(self,name,pay):
        self.person=Person(name,'mgr',pay)

    def giveraise(self, percent, bonus=0.10):
        self.person.giveraise(percent+bonus)

    def __getattr__(self,attr):
        print "calling getattr"
        return getattr(self.person, attr)

    def __setattr__(self,attr, value):
        print "calling setattr"
        self.person__dict__["attr"]=value

    def __str__(self):
        return str(self.person)


if __name__=="__main__":

    sue = Person("sue Jones","dev",10000)
    sue.giveraise(0.10)
    print sue
    print sue.lastName()

    print "- -"*25

    tom = Manager("Tom mandy", 50000)
    tom.giveraise(.10)
    print tom
    print tom.lastName()
4

2 に答える 2

2

mgilson の答えはほぼ正しいですが、__setattr__クラス マネージャーの機能では、間にドットがありませんperson__dict__

def __setattr__(self,attr, value):
        print "calling setattr"
        self.person__dict__["attr"]=value

存在しない属性__init__のクエリである self.person を設定しようとすると、マネージャーの関数が呼び出されます。次に、この段階では存在しない self.person を照会し、この段階で再帰を取得します。__setattr__person__dict____getattr____getattr__

于 2016-11-21T20:58:28.817 に答える