Are functions objects in Python?

前端 未结 2 427
有刺的猬
有刺的猬 2020-12-05 02:40

I always hear this statement in Python (for topics such as decorators, etc. when you are passing functions, etc.) but have never really seen an elaboration on this.

相关标签:
2条回答
  • 2020-12-05 03:16

    You are looking for the __call__ method. Function objects have that method:

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

    Not that the Python interpreter loop actually makes use of that method when encountering a Python function object; optimisations in the implementation jump straight to the contained bytecode in most cases.

    But you can use that on your own custom class:

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

    Demo:

    >>> 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 creates function objects for you when you use a def statement, or you use a lambda expression:

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

    You can compare this to creating a string or an integer or a list using literal syntax:

    listobject = [1, 'two']
    

    The above creates 3 objects without ever calling a type, Python did that all for you based on the syntax used. The same applies to functions.

    Creating one yourself can be a little more complex; you need to have a code object and reference to a global namespace, at the very least:

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

    Here I created a function object by reusing the function type, taking the code object from the foo function; the function type is not a built-in name but the type really does exist and can be obtained by calling type() on an existing function instance.

    I also passed in the global namespace of my interpreter, and a name; the latter is an optional argument; the name is otherwise taken from the code object.

    0 讨论(0)
  • 2020-12-05 03:26

    One simple way to see this is to create a function in the Python interpreter def bar(x): return x + 1 and then use dir(bar) to see the various magic attributes including __class__.

    Yes, python functions are full objects.

    For another approach, objects are functions if they have a magic __call__() method.

    0 讨论(0)
提交回复
热议问题