2017-07-21 6 views
1

オブジェクトのスコープ内の属性にアクセスするオブジェクトに関数を渡すにはどうすればよいですか?Python関数リファレンスオブジェクトの属性

class Foo(): 
    def __init__(self, some_func): 
     self.some_func = some_func 
     self.stats = 'some stats' 
    def execute(self): 
     return self.some_func() 
def bar(): 
    return x.stats  
x = Foo(bar) 
x.execute() 

が、私は、私は、オブジェクトの名前を変更する場合、新しいbarを記述する必要があること嫌い:

これは動作します。私は実際に書きたい何

は、より多くのようなものです:

class Foo(): 
    def __init__(self, some_func): 
     self.some_func = some_func 
     self.stats = 'some stats' 
    def execute(self): 
     return self.some_func() 
def bar(): 
    return self.stats  
x = Foo(bar) 
x.execute() 

bar()selfは、任意のはFooから統計情報を拾うことは関係なく、それが命名だかの、のに渡され得るオブジェクトを持っています。私はこれを行うためのスマートな方法を理解することはできません。

Fooを変更せずにFooオブジェクトの属性を参照する良い方法はありますか?あるいは、Fooの電話番号some_func()をよりスマートにすることでこれを有効にできますか?これは、Python 2と3の間で異なりますか?

+0

これらのアプローチのどちらもNameErrorをスローしませんか? –

+0

「呼び出し側」パラメータを 'bar'に追加してみませんか?基本的には「自己」が通常行うことと同じことです。 def bar(caller):return caller.stats' def execute(self):return self.some_func(self) ' – 0x5453

+0

いいえ。最初の例'x.stats'は' __init__'で 'some_func'を呼び出そうとしたとしても、書かれたように動作します。私はこのような呼び出しを行うコードを継承していると私はそれが小人だと思う。 – aknox

答えて

4

実行時にオブジェクトを渡すことができないのはなぜですか?

class Foo(): 
    def __init__(self, some_func): 
     self.some_func = some_func 
     self.stats = 'some stats' 
    def execute(self): 
     return self.some_func(self) 

def bar(self_): 
    return self_.stats  

x = Foo(bar) 
x.execute() 

上記の関数ためのpython何でbar()作品は、限り、あなたは属性の名前を知っているように、本当にプライベートです。

+0

これは 'eval'関数を使うよりもはるかに良い方法です。代わりに' stats'自体をパラメータとして渡すこともできますが、これははるかにクリーンです。 –

+0

私は実際に 'Foo'を制御しません、' bar() 'だけを制御します。私は 'Foo'の変更を求めることができます。これは' Foo'を使う他の誰もが 'self_'を受け入れることによって自らの' some_func'関数を自明に書き直すことを必要とするという点で比較的軽量です。他の多くの人がFooを使い、 'some_func'でやっていることは' stats'や 'self'を必要としないかもしれません。 – aknox

+0

追加オプションがあります:名前をほとんど変更しない関数が少数しかない場合は、 'bar()'のような追加関数を使って 'Foo'の各インスタンスをサルでパッチすることができます。あなたは 'Foo'をインスタンス化する(または' __init __() 'に渡された独自のクラスを作成し、未知のメソッド呼び出しを' Foo'インスタンスに転送することができます。 – quamrana