2011-01-16 14 views
1

本を読んで役立つ__getattr__、私は...このコードに出くわしたPythonは

# module person.py 

class Person: 

    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(): 
    def __init__(self, name, pay): 
     self.person = Person(name, "mgr", pay) 

    def giveRaise(self, percent, bonus=.10): 
     self.person.giveRaise(percent + bonus) 

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

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

それは、私はそれが何をしたいのかない、しかし、私はManagerクラスで__getattr__機能を理解していません。私はそれがPersonクラスの他のすべての属性を委譲することを知っています。私はそれが動作する方法を理解していません。なぜPersonクラスからですか?私は明示的にそれを伝えていないので。人は(モジュールは、すべてのヘルプは高く評価されて

人(クラス)とは異なります:)実は

+2

コードが古いか悪いか、その背後にあるトリックは表示されません。しかし、 'Manager'クラスに' Person'を継承させるだけです。しかし、私は本当にあなたの質問を理解していません。あなたは 'getattr'がやっていることを知っていると言います。なぜそれが 'self.person'に委譲されたのかについて:私はこのコードを書いていないので、' Manager'が 'Person'だと仮定することができます。コンストラクタでは、新しい 'Person'が作成されます。 –

+2

これは本当に古いコードです: 'object'からサブクラス化されないので、古いスタイルのクラスです。ああ、それは壊れています: 'Person.lastName'は" de la Garza "という姓の人に正解を返しません。 –

+0

あなたはどんな本を読んでいますか?これは、ひどく書かれたimhoを見ています... – ChristopheD

答えて

0

、明示的にそれを教えてください - ないクラスを命名することではなく、そのクラスのインスタンスを提供することで。

initメソッドでは、self.personPersonのインスタンスにバインドします。さて、すべてのManagerインスタンスにこのデータメンバーがあります。

__getattr__には、の組み込み先を第1引数としてgetattrに委任しています。 self.personのタイプに関係なく、指定された名前のメンバーが検索されます。あなたの__init__あなたがself.personに割り当てられますPersonオブジェクトをインスタンス化して

+0

私はマネージャオブジェクトを作成する場合:m =マネージャ( "Fred"、1200)、なぜm.personはm.person.personになってしまいますか? – Spacedman

2
  1. 次に、(この特定のケースでは1からPerson目的である)(このクラスの__getattr__を実装することにより)Managerインスタンスに属性検索を無効にし、代わりにself.person変数を見上げなければ、これらの属性をリダイレクト。

フェリックスクリングがコメントで述べたように、それはPersonからManager継承を作るために、より理にかなって。上記の現在のコードでは、マネージャーには人がいるように見えますが、マネージャーは人だと考えるのがより論理ですが、

あなたはこのような何かを行うことができます:

class Person(object): 

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

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

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

class Manager(Person): 

    def __init__(self, name, pay): 
     super(Manager, self).__init__(name, "mgr", pay) 

    def give_raise(self, percent, bonus=.10): 
     self.pay = int(self.pay * (1 + (percent + bonus))) 

# example usage 
John = Person("John", "programmer", 1000) 
Dave = Manager("Dave", 2000) 
print John, Dave 
John.give_raise(.20) 
Dave.give_raise(.20) 
print John, Dave 
0

本を読ん横に、あなたは__getattr__()の方法がどのように動作するかのかなり明確な説明を見つけることができたThe Bookに相談することをお勧めします。

nutshellは、指定された名前の属性が適用されているオブジェクトにアタッチされていないときに呼び出され、オブジェクトクラスまたはそのスーパークラスの属性にもアタッチされません。つまり、他のすべてが失敗したときに呼び出されます。

例のコードでは、__getattr_()の実装は、Personクラスのインスタンスであるself.personオブジェクトに、指定された属性の検索を効果的にリダイレクトします。

__getattr_()は、データとオブジェクトに関連付けられたメソッドの両方にアクセスする最初のステップであることを理解することも重要です。