21
class Foo(object):
    def tick(self):
        print("something")

class Bar(object):
    def __init__(self):
        self.foo = Foo()

    def tick(self):
        #Here's what I do....
        self.foo.tick()

        #here's what my goal would be
        self.foo()

b = Bar()
b.tick()

それが本質的に私の目標です。私が集めたものから、ティック関数をに変更することができ__call__、それによって私がやりたいことができるようになります。他のいくつかの回答は、これがオブジェクトの新しいインスタンスを作成すると言いましたが、それは self.foo のメモリを使用することを意味しますか? それとも、新しくインスタンス化されたまったく新しいオブジェクトを作成しますか? またはself.fooのコピーを作成しますか?

また、これにはいくつかの欠点があり、それが現れる場合と現れない場合があります。__call__プログラムの特定の部分について、渡した引数が関数なのか変数なのかを判断するために、オブジェクトにとはいえ、クラスは技術的にはその時点で関数になると思います。)関数と呼び出し可能なクラスを区別する方法はありますか?

これを望ましくないものにするものは他にありますか? __私の次の考えは、 cant という接頭辞が付いた他の変数をクラス外で使用できないことを考えると、そうではないようです。

4

2 に答える 2

26

に変更tick(self)する__call__(self)のが正しい解決策です。

これはメモリ割り当てとは関係ありません。すべての意味は、(オブジェクトに対して) 構文__call__を使用するときに Python が呼び出す関数です。foofoo()

後の質問について: 何かがオブジェクトかどうかを確認するには、isinstanceorを使用しますissubclass(おそらくobjectクラスで)。そして、私の考えでは、この答えは、「何かが関数であるかどうかをどのように判断しますか?」に対して受け入れられたものよりも優れています。おそらく見たことのある質問。

于 2013-01-29T15:14:01.227 に答える
22

クラス インスタンスを呼び出し可能にするには、__call__メソッドを実装するだけです。次に、__call__メソッド を呼び出すにはinstance(arg1,arg2,...)、次のようにします。つまり、関数を呼び出すのと同じ方法でインスタンスを呼び出します。

__call__必要に応じて、クラスで定義された他のメソッドでエイリアスできることに注意してください。

>>> class Foo(object):
...     def tick(self):
...         print ("something")
...     __call__ = tick
... 
>>> a = Foo()
>>> a()
something
>>> a.tick()
something
于 2013-01-29T15:17:41.107 に答える