我已经阅读了PEP 3107的前几节,但我仍然没有得到他们为语言做的好事。在我看来,您可以使用装饰器向函数添加元数据。 e.g。
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)."): ...
至少我最初的印象是注释是多余的:装饰者可以做注释可以做的所有事情(以及更多)。在为函数添加元数据时,为什么注释比装饰器更好?
答案 0 :(得分:32)
正如您所提到的,相关的PEP是3107(如果其他人遇到此问题尚未阅读,则链接以便于参考)。
目前,注释是一种实验,是一种正在进行的工作。实际上python-ideas mailing list中有关于该主题的最新帖子可能会有所帮助。 (提供的链接仅用于月度存档;我发现特定帖子的URL往往会定期更改。有问题的线程在12月初附近,标题为“[Python-ideas]功能注释约定”。第一篇文章来自12月1日的Thomas Kluyver。)
以下是Guido van Rossum在该主题中的帖子之一:
12/12/2012 11:43 AM,Jasper St. Pierre写道:
事实上。我以前看过注释,但我从来没有理解过 目的。它似乎是一个没有设计和实现的功能 一些目标,以及社区应该发现目标的地方 自己。
Guido的回应:
恰恰相反。有太多的用例立即显示出来 很重要,我们无法弄清楚哪些是最重要的 重要或如何将它们结合起来,所以我们决定采取两步措施 方法:在步骤1中,我们设计了语法,而在第2步中,我们设计了语法 会设计语义。这个想法很明显,曾经的 语法得到解决,人们可以自由地尝试不同的 语义 - 只是不在stdlib中。这个想法也是如此 最终,从所有这些实验中,都会出现 适合stdlib。
Jasper St. Pierre:
所以,如果我可以问一下,注释的最初目标是什么? PEP给出了 一些建议,但不会留下任何具体的东西。是它的设计 IDE的辅助工具,还是检查源代码的静态分析工具?某物 为应用程序本身提供特殊行为, 像命令行解析器,还是运行时静态检查器?
Guido的回应:
在某种程度上几乎所有上述内容。但对我个人而言, 主要目标始终是达到指定类型的符号 参数和返回的约束(以及可能的其他约束) 值。我通过特定的组合方式在不同的时间玩弄 类型。例如。 list [int]可能意味着一个整数列表,并且dict [str, 元组[float,float,float,bool]]可能意味着将字符串映射到的字典 三个花车和一个布尔的元组。但我觉得这要难得多 对于这样的符号而不是关于参数的语法的共识 注释(想想你可以带来多少反对意见 两个例子:-) - 我一直强烈希望使用“var:type = default“并使类型成为要计算的运行时表达式 与默认值同时发生。
来自Ned Batchelder的一点点幽默:
对我而言,一个充满希望的时刻是在PyCon的早期Py3k主题演讲中(也许是 它是在达拉斯还是芝加哥?),Guido不记得这个词了 “注释”,并说,“你知道,那些不是类型的东西 声明?“: - )
答案 1 :(得分:8)
我认为第一段说明了一切:
因为Python的2.x系列缺少注释函数参数和返回值的标准方式
(强调我的)
采用标准方法执行此操作的好处是您可以确切地知道注释的位置。
至于你关于另一种方法的论点,你可以针对列表推导做出相同的论证:
out = []
for x in my_iterable:
out.append(x)
答案 2 :(得分:6)
他们有两个不同的角色。
注释是参数的文档/注释,而装饰器转换函数。
Python本身并没有对注释附加任何特定的含义或意义。
装饰器动态地改变函数,方法或类的功能,而不必直接使用子类或更改正在装饰的函数的源代码。