在Python中将函数作为对象处理

时间:2014-04-30 23:49:44

标签: 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确实是类类型?

3 个答案:

答案 0 :(得分:5)

Pep 232为该语言添加了“函数属性”。如果你想要所有官方推理,你可以阅读。情况的现实归结为介绍中的这句话:

  

func_doc有   有趣的属性,功能中有特殊的语法(和       方法)隐式设置属性的定义。 :此       便利性一再被剥削,超载       带有附加语义的docstrings。

强调我的。人们使用__doc__属性来走私各种功能元数据;提供一个真正的地方似乎更自然。

至于一些更具体的问题:

  

函数是对象吗?

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

def increment(x):
    return x+1

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

我还需要哪种类型的功能呢?

你一般不这样做。不经常。但是,当您想要存储有关函数的元数据时,它会很有用。

说我想用一个装饰器来包装一个函数,该装饰器记录它被调用了多少次。这很简单,因为我们可以将这些信息放入函数的__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

答案 1 :(得分:1)

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

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

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

我见过的另一个用途是装扮器,它计算了一个函数被调用的次数:

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

答案 2 :(得分:0)

部分引用学习Python(Mark Lutz):

  

与Python中的其他内容一样,函数只是对象;他们是   在程序执行时明确记录在内存中。事实上,   除了调用之外,函数还允许附加任意属性   记录信息供以后使用。

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