2012-01-24 8 views
0

次のコードを持つと、クラス属性に割り当てられていてもバインドされないように 'foo'関数を使って何ができますか? __get__をオーバーライドすることは役に立ちません - インスタンスの__dict__に関数が存在しない場合には使用されないので、私が理解する限り理解します(クラス属性の場合もそうです)。 他に何ができますか?クラス属性に割り当てられていても、Python関数を常にアンバインドにする方法

def foo(x): 
    print(x) 

def foo_get(self, obj, type=None): 
    return foo 

foo.__get__ = foo_get 

class A(object): 
    def __init__(self): 
     self.f = foo 
class B(object): 
    f = foo 


a = A() 

print(a.f)    #<function foo at 0x2321d10> 
print(a.f.__get__(a, A)) #<function foo at 0x2321d10> 

b = B() 

print(b.f)    #<bound method B.foo of <__main__.B object at 0x23224d0>> 
+4

なぜあなたはこれをしたいですか? –

+0

私は、元のvergionと猿のパッチを当てたものとの間に違いがないように、猿パッチのbuiltin thread.start_new_threadにそれを必要とします。今では、クラス属性にwait_new_threadを代入すると(ウェイトレスライブラリはそれを行います)、それを使用します。元のバージョンは、いつもタイプ組み込み関数を持っているので動作し、monkey-patchはそれがバインドされても機能しません。 –

+0

しかし 'thread.start_new_thread'はクラスのメソッドではありません。それは '<組み込み関数start_new_thread>'です。置き換えたい場合は 'thread.start_new_thread'に代入し、それに普通の関数を与えるだけです。 –

答えて

6

私はかなりあなたがほしいと確信しています@staticmethod

foo = staticmethod(foo)

また、呼び出し可能なクラスに__get__を定義することができます。

class Foo(object): 
    def __get__(self, obj, type=None): 
     return self 

    def __call__(self, x): 
     print(x) 

foo = Foo() 

class A(object): 
    def __init__(self): 
     self.f = foo 
class B(object): 
    f = foo 


foo(1) # 1 
a = A() 

a.f(1) # 1 
print(a.f)    #<function foo at 0x2321d10> 
print(a.f.__get__(a, A)) #<function foo at 0x2321d10> 

b = B() 
b.f(1) # 1 


print(b.f)    #<__main__.Foo object at 0x7fa8c260be10> 

は、これは、1つのインデントの余分なレベルとコードのいくつかの余分なラインだが、それはそれはだ場合、それは、どのように行うことができるかです重要。

+0

staticmethodを試しましたが、別の問題が発生しました。fooを単独で使用することはできません。 TypeError: 'staticmethod'オブジェクトは呼び出し可能ではありません。 –

+0

更新されました。 stdlib関数をmonkeypatchingとして...注意してください。あなたがしようとしていることは他の場所ではできないのですか? – AdamKG

+0

ブラボーアダム! Callableクラスは実際にここで動作します。ありがとうございました。 –

関連する問題