web-dev-qa-db-ja.com

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

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

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

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

あなたが持つことができるように

c(whatever parameters are required)

私はここでの理解でうまく行かなくなる可能性があります、私は人々がこれが何を意味するのか知りたいだけでした。

21
user3684792

___call___メソッド を探しています。関数オブジェクトにはそのメソッドがあります:

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

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

しかし、あなたはcan独自のカスタムクラスでそれを使用します。

_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ステートメントorを使用すると、関数オブジェクトを作成します = 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()を呼び出すことで取得できます。

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

30
Martijn Pieters

これを確認する簡単な方法の1つは、Pythonインタープリターdef bar(x): return x + 1で関数を作成し、dir(bar)を使用して___class___。

はい、python関数は完全なオブジェクトです。

別のアプローチでは、オブジェクトが magic __call__() method を持っている場合、オブジェクトは関数です。

5
shapr