次のようなコードがあります:
class A(object):
@staticmethod
def open():
return 123
@staticmethod
def proccess():
return 456
switch = {
1: open,
2: proccess,
}
obj = A.switch[1]()
これを実行すると、次のエラーが発生し続けます:
TypeError: 'staticmethod' object is not callable
どうすれば解決できますか?
ベストアンサー1
保存しています縛られない staticmethod
辞書内のオブジェクト。このようなオブジェクト(およびclassmethod
オブジェクト、関数、property
オブジェクト)は、記述子プロトコルクラスまたはインスタンスの属性として名前にアクセスすることによって、staticmethod
属性アクセスが可能になります。クラス本体のオブジェクトに直接アクセスすることは、属性アクセスではありません。
辞書を作成するか後クラスを作成するか(属性としてアクセスする)、明示的にバインドするか、辞書に格納する前に元の関数を抽出します。
オブジェクトの「バインディング」は、staticmethod
単にコンテキストが無視されることを意味するだけであることに注意してください。バインドは、staticmethod
基になる関数を変更せずに返します。
したがって、オプションとしては、辞書のインデントを解除し、属性を使用して記述子プロトコルをトリガーします。
class A(object):
@staticmethod
def open():
return 123
@staticmethod
def proccess():
return 456
A.switch = {
1: A.open,
2: A.proccess,
}
または、ダミーのコンテキスト(いずれにせよ無視されます)を渡して明示的にバインドします。
class A(object):
@staticmethod
def open():
return 123
@staticmethod
def proccess():
return 456
switch = {
1: open.__get__(object),
2: proccess.__get__(object),
}
または、属性を使用して基礎となる関数に直接アクセスします__func__
。
class A(object):
@staticmethod
def open():
return 123
@staticmethod
def proccess():
return 456
switch = {
1: open.__func__,
2: proccess.__func__,
}
しかし、あなたがしようとしているのが、名前空間関数を大量に必要とする場合は、クラスオブジェクトをそもそも使用すべきではありません。関数をモジュールstaticmethod
そうすれば、最初からデコレータを使用する必要がなくなり、再度アンラップする必要もなくなります。