Python 中的函数是对象吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25292239/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 20:01:07  来源:igfitidea点击:

Are functions objects in Python?

pythonfunctionclassmethods

提问by user3684792

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.

我总是在 Python 中听到这样的声明(对于诸如装饰器之类的主题,当您传递函数等时),但从未真正看到过对此的详细说明。

For example is it possible to create a class cthat has only one abstract method that is called with a set of opened and closed brackets.

例如,是否可以创建一个c只有一个抽象方法的类,该方法用一组开括号和闭括号调用。

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

so you can have

所以你可以拥有

c(whatever parameters are required)

I could be way off the mark with my understanding here, I was just curious about what people meant by this.

我在这里的理解可能有点离题,我只是好奇人们的意思是什么。

采纳答案by Martijn Pieters

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

您正在寻找__call__方法。函数对象具有该方法:

>>> 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.

并不是说 Python 解释器循环在遇到 Python 函数对象时实际上会使用该方法;在大多数情况下,实现中的优化直接跳转到包含的字节码。

But you canuse 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 youwhen you use a defstatement, oryou use a lambdaexpression:

Python的创建函数对象为你当你使用def的语句或者你使用一个lambda表达式

>>> 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.

上面创建了 3 个对象,但从未调用过类型,Python 根据使用的语法为您完成了所有操作。这同样适用于函数。

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 functiontype, taking the code object from the foofunction; 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.

这里我通过重用function类型创建了一个函数对象,从foo函数中取出代码对象;函数类型不是内置名称,但该类型确实存在并且可以通过调用type()现有函数实例获得。

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.

我还传入了我的解释器的全局命名空间和一个名称;后者是一个可选参数;否则名称取自代码对象。

回答by shapr

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

查看这一点的一种简单方法是在 Python 解释器中创建一个函数def bar(x): return x + 1,然后使用dir(bar)它查看各种魔法属性,包括__class__.

Yes, python functions are full objects.

是的,python 函数是完整的对象。

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

对于另一种方法,如果对象具有魔法__call__()方法,则它们就是函数。