Python函数注释有什么用?

时间:2012-12-09 04:40:19

标签: python python-3.x

我已经阅读了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)."): ...

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

3 个答案:

答案 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本身并没有对注释附加任何特定的含义或意义。

Python Decorators page

  

装饰器动态地改变函数,方法或类的功能,而不必直接使用子类或更改正在装饰的函数的源代码。