Python 中的函数是对象吗? [英] Are functions objects in Python?

查看:20
本文介绍了Python 中的函数是对象吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

例如,是否可以创建一个 c 类,它只有一个抽象方法,该方法用一组左括号和右括号调用.

即c类:@抽象方法def method_to_be_Called_by():...

所以你可以拥有

c(需要什么参数)

我的理解可能有点离题,我只是好奇人们的意思.

解决方案

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

<预><代码>>>>def foo(): 通过...>>>foo.__call__<0x106aafd70 处函数对象的方法包装器__call__">

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

但是你可以在你自己的自定义类中使用它:

类可调用(对象):def __init__(self, name):self.name = 姓名def __call __(自我,问候):返回 '​​{}, {}!'.format(greeting, self.name)

演示:

<预><代码>>>>类可调用(对象):... def __init__(self, name):... self.name = 姓名... def __call__(self, greeting):... return '{}, {}!'.format(greeting, self.name)...>>>Callable('世界')('你好')'你好世界!'

当您使用 def 语句您使用lambda 表达式:

<预><代码>>>>def foo(): 通过...>>>富<函数 foo 在 0x106aafd70>>>>拉姆达:无<函数<lambda>在 0x106d90668>

您可以将其与使用文字语法创建字符串或整数或列表进行比较:

listobject = [1, '二']

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

自己创建一个可能会更复杂一些;您至少需要有一个代码对象和对全局命名空间的引用:

<预><代码>>>>函数类型 = 类型(拉姆达:无)>>>函数类型<输入'函数'>>>>function_type(foo.__code__, globals(), 'bar')<0x106d906e0处的功能栏>

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

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

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.

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

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.

解决方案

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.

这篇关于Python 中的函数是对象吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆