在Python中将函数视为对象

2024-10-05 14:23:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我不确定标题是否与我将要问的问题匹配,但如果您知道一个更好的标题可以帮助所有人,请随时更新。

假设我们有以下定义:

>>> def helloFunction():
        name = "Hello World"

所以当我输入下面的代码时,它返回一个空字典。你知道吗

>>> helloFunction.__dict__
{}

我不确定这是否应该是这样,但让我们继续。有趣的是,我可以做到以下几点:

>>> helloFunction.hello = "world"
>>> helloFunction.__dict__
{'hello': 'world'}

当我输入下面的代码时,它告诉我helloFunction确实是一个函数。你知道吗

>>> type(helloFunction)
<type 'function'>

我来自C#,这种行为对我来说有点奇怪。为什么Python是这样工作的?函数是对象吗?我该如何解释这种情况?我在哪里需要这种功能?你知道吗

更新

当我写这个问题时,我意识到__class__是在helloFunction上定义的。你知道吗

>>> helloFunction.__class__
<type 'function'>

所以看起来function确实是一个类类型?你知道吗


Tags: 函数代码name标题helloworld定义def
3条回答

函数是一个对象,与Python中的大多数对象一样,它有一个字典。我在野外看到的一个使用示例是web框架CherryPy,它用于指示哪些方法可以访问web:

import cherrypy
class HelloWorld(object):
    def index(self):
        return "Hello World!"
    index.exposed = True

当访问路径时,调度器可以检查相应的处理程序方法是否将其exposed属性设置为True并对其作出响应,从而允许在控制器上安全地定义可访问方法和私有方法。你知道吗

我见过的另一个用法是一个decorator,它计算函数被调用的次数:

def call_counter(fn):
    fn.count = 0
    def _fn(*args, **kwargs):
        fn.count += 1
        return fn(*arg, **kwargs)
    return _fn

Pep 232在语言中添加了“函数属性”。如果你想知道所有的官方理由,你可以读一下。现实情况可以归结为引言中的这句话:

func_doc has the interesting property that there is special syntax in function (and method) definitions for implicitly setting the attribute. This convenience has been exploited over and over again, overloading docstrings with additional semantics.

我的。人们使用__doc__属性来走私各种各样的函数元数据;提供这样做的真实场所似乎更为自然。你知道吗

至于一些更具体的问题:

Is a function an object?

哦,是的。函数是python中的一级对象。您可以将对它们的引用作为参数传递给您喜欢的其他函数。如果他们不是一流的,我不能这样做:

def increment(x):
    return x+1

map(increment,[1,2,3]) # python2 `map`, for brevity
Out[3]: [2, 3, 4]

And also where would I need this type of functionality?

你一般不会。不经常。但当您想存储有关函数的元数据时,它可能很有用。你知道吗

假设我想用一个decorator来包装一个函数,这个decorator记录函数被调用的次数。这很简单,因为我们可以将这些信息塞进函数的__dict__。你知道吗

def count_calls(func):
    def _inner(*args, **kwargs):
        before = getattr(func,'times_called',0)
        func.times_called = before + 1
        print('func has now been called {} times'.format(func.times_called))
        return func(*args,**kwargs)
    return _inner

@count_calls
def add(x,y):
    return x+y

add(3,4)
func has now been called 1 times
Out[7]: 7

add(2,3)
func has now been called 2 times
Out[8]: 5

部分引自《学习Python》(Mark Lutz):

Like everything else in Python, functions are just objects; they are recorded explicitly in memory at program execution time. In fact, besides calls, functions allow arbitrary attributes to be attached to record information for later use.

def func(): ... # Create function object
func() # Call object
func.attr = value # Attach attributes

相关问题 更多 >