1. ホーム
  2. python

[解決済み] staticmethod' オブジェクトは呼び出し可能ではない

2022-12-30 19:39:24

質問

このようなコードがあります。

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

どのように解決するのですか?

どのように解決するのですか?

保存している バインドされていない 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 のデコレータを使う必要がなくなり、またアンラップする必要もなくなります。