函数注释似乎重复了Python中已有的行为。不仅如此,它们所具有的含义并没有以任何方式强制执行,因此它们可以用于PEP 3107中记录的以下任何内容
让IDE显示函数所需的类型和重载/通用functions
甚至是一些完全不同的东西。
在某种程度上,函数注释让我想起了Python's humour collection中的一个老笑话
Python实际上已经支持块delimiters:
if foo: #{ > foo1(); > foo2(); > foo3(); > #}
在那里面
def foo(a: 'x', b: 5 + 6, c: list) -> max(2, 9):
...
并不比以下内容更有用:
# a: 'x', b: 5 + 6, c: list
def foo(a, b, c): #-> max(2, 9):
...
有人可能会争辩说,函数注释是必要的,因为与注释不同的是,它们可以从代码中访问,例如:
>>> def spam(a: 'eggs') -> 'ni!':
... pass
...
>>> spam.__annotations__
{'a': 'eggs', 'return': 'ni!'}
尽管同样的行为可以很容易地通过装饰器实现,比如:
def param(**kw):
def decorator(func):
def wrap(*args):
print kw
func(*args)
return wrap
return decorator
def return_(arg):
def decorator(func):
def wrap(*args):
func(*args)
print arg
return wrap
return decorator
@param(a='eggs')
@return_('ni!')
def spam(a):
pass
spam(None)
# Output:
# -------
## {'a': 'eggs'}
## ni!
Python已经可以做注解所做的事情,那么为什么函数注解需要专用的语法呢?
编辑:我将对我的问题做一点扩展,因为它的意思已经被证明是稍微不清楚的。
我特别问这个问题是关于函数注释的,而不是装饰器的。
@decorator
def spam():
pass
是的缩写
def spam():
pass
spam = decorator(spam)
和方法调用,其中
self.method(param)
是的缩写
Class.method(self, param)
有了这两个简写的语法快捷键,它们的含义就不能。我不是在问,既然已经有了替代方案,为什么需要这样的捷径;这是一个可读性问题。函数注释与这两个快捷键略有不同,因为
def spam() -> int:
pass
和
def spam() -> 'integer':
pass
可能与人类具有相同的含义,但不会与计算机具有相同的含义。即使程序员知道注释应该定义什么,对于注释如何定义它也没有达成一致的定义。此外,注释不会影响功能,因此没有一致性的要求。
下面是我修改后的问题:
当函数注解提供了一种可改变且可能不一致的方式来访问已经存在的语言功能时,为什么它们需要专用的语法呢?为什么没有关于如何使用注释的强制定义,而它们可以用于什么方面有一个完美的定义(PEP 3107)?
发布于 2012-08-31 02:53:31
您链接到的PEP 3107似乎在其“基本原理”部分为您的问题提供了答案:
基本原理
由于Python2.x系列缺乏注释函数参数和返回值的标准方法,因此出现了各种工具和库来填补这一空白。有些利用了“PEP318”中引入的装饰器,而另一些则解析函数的文档字符串,查找那里的注释。
这个PEP旨在提供一种单一的、标准的方式来指定这些信息,减少由于机制和语法的巨大差异而造成的混乱,直到现在。
发布于 2012-08-31 02:54:17
装饰器语法的意义是什么?它不允许你做任何你以前不能做的事情:
@staticmethod
def foo():
pass
就是
def foo():
pass
foo = staticmethod(foo)
但是装饰器的语法更好。
在这两个中,哪一个更好:
@param(a='eggs')
@return_('ni!')
def spam(a):
pass
def spam(a: 'eggs') -> 'ni!':
pass
意见可能不同,但我认为第二种更好。
发布于 2018-07-12 03:23:52
我非常喜欢类型注解,因为它们可以被我的集成开发环境PyCharm识别。通过注释类型,PyCharm将在我编码时知道变量的类型。这使我可以在可能不完全记住其名称的类中找到所需的函数,并在不实际查看该类的代码/文档的情况下查找它们。
正如您所说的,与注释不同,类型注释可以从代码中访问。这是一笔巨大的交易,因为它允许创建确保类型的类,并基于成员指定的类型提供其他功能。
https://stackoverflow.com/questions/12203468
复制相似问题