2012-12-09 53 views
33

我已经经历了PEP 3107中的前几个部分,但我仍然没有得到他们为该语言做了什么好事。在我看来,你可以使用装饰器添加元数据到函数。例如Python函数注释有什么好处?

def returns(return_type): 
    f.return_type = return_type # <- adding metadata here 
    return f 

@returns(Foo) 
def make_foo(): ... 

您可以添加元数据来论证过了,它可以看起来很漂亮,如果你利用缺省参数,就像这样:

import inspect 

def defaults_are_actually_metadata(f): 
    names, args_name, kwargs_name, defaults = inspect.getfuncspec(f) 
    f.parameter_metadata = dict(zip(names[-len(defaults):], defaults)) 
    f.__defaults__ =() 
    return f 

@defaults_are_actually_metadata 
def haul(load="Stuff to be carried.", 
     speed_mph="How fast to move the load (in miles per hour)."): ... 

至少我的初步印象是,注释是多余的:装饰可以做所有注释可以(和更多)。为元数据添加到函数时,为什么注释比装饰器更好?

+4

现在,注释是一种实验,也是一种正在进行的工作,实际上[python-ideas邮件列表]中有一个最近的线程(http://mail.python .org/pipermail/python-ideas/2012-December/thread.html)可能会有所帮助。 –

+0

@JohnY我想将您的答案标记为“正确”,但这不是“官方”答案! – allyourcode

回答

31

正如您所提到的,相关的PEP为3107(链接为便于参考,以防其他人遇到此问题尚未阅读)。

现在,注释是一种实验,也是一种正在进行的工作。实际上,关于该主题的python-ideas mailing list最近有一个线索,可能会有所帮助。 (提供的链接仅用于每月的归档;我发现特定帖子的URL会定期更改,所涉及的线程接近12月初,标题为“[Python-ideas]约定用于函数注释”。第一篇文章是从托马斯Kluyver 12月1)

下面是吉多·范罗苏姆在该线程的职位之一位:

在2012年12月4日上午11点43分,碧玉圣Pierre写道:

确实。我以前看过注释,但我从来不明白 的目的。这似乎是一个功能,其设计和实施没有 一些目标,社区本应该发现目标 本身。

圭多的回答是:

相反。有太多的用例立即显示为 重要的,我们无法弄清楚哪些将是最重要的或如何组合它们,因此我们决定采取两步式 方法:在第1步中,我们设计语法,而在步骤2中,我们 将设计语义。这个想法非常清楚,一旦 语法解决了,人们就可以自由地尝试不同的 语义 - 只是不在stdlib中。这个想法也是最后,从所有这些实验中,将会出现适合stdlib的 。

碧玉圣皮埃尔:

所以,如果我可能会问,什么是注释的原始目标是什么? PEP给出了 一些建议,但没有留下任何具体的东西。它是否设计为 对IDE的帮助或检查源代码的静态分析工具? 为应用程序本身提供特殊行为, 像命令行解析器或运行时静态检查器?

圭多的回答是:

几乎所有上述的在一定程度上。但对我个人而言, 的主要目标是始终为符号指定 约束(也许还有其他约束),并返回 值。我在不同的时间玩过 类型的特定方式。例如。 list [int]可能意味着一个整数列表,并且字典[str, tuple [float,float,float,bool]]可能意味着将字符串映射到 三个浮点数和一个布尔值的元组。但是我觉得 对于这样一个符号而不是关于参数 注释的语法很难得到一致意见(想想你可以引入多少个反对意见,例如:-) - 我总是有一个强大的希望使用“var: = default”并使该运行时表达式与缺省值同时被计算为 。

而且从斯内德尔德幽默一点点:

我一个生动的时刻是在PYCON早期Py3k的主题演讲中(?也许 它是在达拉斯或芝加哥),圭多couldn”不要忘记 这个词的“注释”,并说:“你知道,那些不是 类型的东西的声明?“:-)

8

我认为,第一款规定了一切:

因为Python的2.x的系列没有标注函数的参数和返回的标准路值

(重点煤矿)

有一个标准的方法来做到这一点的好处是,你确切知道注释的位置。

至于你的论点大约有另一种方式做到这一点,你可以把对列表推导相同的参数:

out = [] 
for x in my_iterable: 
    out.append(x) 
6

他们有两个不同的角色。

注释是参数的文档/注释,而装饰器转换函数。

Python本身并没有给注释赋予任何特殊的含义或意义。

Python Decorators page

装饰动态改变的函数,方法或类的功能,而不必直接使用亚类或改变的功能被装饰的源代码。