我不确定标题是否与我要提出的问题相符,但如果你知道一个更好的标题可以帮助每个人,请随时更新。
所以我们假设我们有以下定义:
>>> 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
确实是类类型?
答案 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