Pythonでは関数はオブジェクトですか? 質問する

Pythonでは関数はオブジェクトですか? 質問する

私はいつも Python でこのステートメントを耳にします (関数を渡すときのデコレータなどのトピックなど) が、これについて詳しく説明されているのを見たことはありません。

たとえば、c開き括弧と閉じ括弧のセットで呼び出される抽象メソッドを 1 つだけ持つクラスを作成することは可能です。

i.e class c:
       @abstractmethod
       def method_to_be_called_by():
        ... 

だからあなたは

c(whatever parameters are required)

私の理解は大きく外れているかもしれませんが、私はただ人々がこれによって何を意味しているのか知りたかったのです。

ベストアンサー1

あなたが探しているのは__call__方法関数オブジェクトには次のメソッドがあります。

>>> def foo(): pass
... 
>>> foo.__call__
<method-wrapper '__call__' of function object at 0x106aafd70>

Python インタープリタ ループは、Python 関数オブジェクトに遭遇したときに実際にそのメソッドを使用するわけではありません。実装の最適化により、ほとんどの場合、含まれるバイトコードに直接ジャンプします。

でもあなたはできるこれを独自のカスタムクラスで使用します。

class Callable(object):
    def __init__(self, name):
        self.name = name

    def __call__(self, greeting):
        return '{}, {}!'.format(greeting, self.name)

デモ:

>>> class Callable(object):
...     def __init__(self, name):
...         self.name = name
...     def __call__(self, greeting):
...         return '{}, {}!'.format(greeting, self.name)
... 
>>> Callable('World')('Hello')
'Hello, World!'

Pythonは関数オブジェクトを作成するあなたのためにを使用するとdef声明またはあなたはlambda表現:

>>> def foo(): pass
... 
>>> foo
<function foo at 0x106aafd70>
>>> lambda: None
<function <lambda> at 0x106d90668>

これを、リテラル構文を使用して文字列、整数、またはリストを作成する場合と比較することができます。

listobject = [1, 'two']

上記では、型を呼び出さずに 3 つのオブジェクトを作成します。Python は、使用されている構文に基づいてこれをすべて実行しました。関数にも同じことが当てはまります。

自分で作成するのは少し複雑です。少なくとも、コード オブジェクトとグローバル名前空間への参照が必要です。

>>> function_type = type(lambda: None)
>>> function_type
<type 'function'>
>>> function_type(foo.__code__, globals(), 'bar')
<function bar at 0x106d906e0>

functionここでは、関数からコード オブジェクトを取得し、型を再利用して関数オブジェクトを作成しましたfoo。関数型は組み込み名ではありませんが、型は実際に存在し、既存の関数インスタンスを呼び出すことによって取得できますtype()

また、インタープリターのグローバル名前空間と名前も渡しました。後者はオプションの引数で、それ以外の場合はコード オブジェクトから名前が取得されます。

おすすめ記事