我总是在Python中听到这个声明(对于诸如装饰器之类的主题,当你传递函数时等)但是从未真正看到过这方面的详细说明。
例如,是否可以创建一个只有一个抽象方法的类c
,该方法使用一组打开和关闭的括号进行调用。
i.e class c:
@abstractmethod
def method_to_be_called_by():
...
所以你可以拥有
c(whatever parameters are required)
我的理解可能与我的理解不符,我只是对这个人的意思感到好奇。
答案 0 :(得分:30)
您正在寻找__call__
method。函数对象具有以下方法:
>>> 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!'
当您使用def
statement,或使用lambda
expression时,Python会为您创建 功能对象:
>>> 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()
来获取。
我还传入了我的解释器的全局命名空间和一个名字;后者是一个可选的论点;否则从代码对象中获取名称。
答案 1 :(得分:5)
一种简单的方法是在Python解释器def bar(x): return x + 1
中创建一个函数,然后使用dir(bar)
查看各种魔术属性,包括__class__
。
是的,python函数是完整的对象。
对于另一种方法,如果对象具有magic __call__()
method,则它们是函数。