首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么Python中的函数注释需要专用语法?

为什么Python中的函数注释需要专用语法?
EN

Stack Overflow用户
提问于 2012-08-31 02:45:37
回答 3查看 878关注 0票数 5

函数注释似乎重复了Python中已有的行为。不仅如此,它们所具有的含义并没有以任何方式强制执行,因此它们可以用于PEP 3107中记录的以下任何内容

让IDE显示函数所需的类型和重载/通用functions

  • Foreign-language bridges

  • Adaptation

  • Predicate逻辑functions

  • Database marshaling

  • Other information

  • Documentation
  • RPC marshaling
  • Other information
  • Documentation

甚至是一些完全不同的东西。

在某种程度上,函数注释让我想起了Python's humour collection中的一个老笑话

Python实际上已经支持块delimiters:

if foo: #{ > foo1(); > foo2(); > foo3(); > #}

在那里面

代码语言:javascript
复制
def foo(a: 'x', b: 5 + 6, c: list) -> max(2, 9):
    ...

并不比以下内容更有用:

代码语言:javascript
复制
# a: 'x', b: 5 + 6, c: list
def foo(a, b, c):  #-> max(2, 9):
    ...

有人可能会争辩说,函数注释是必要的,因为与注释不同的是,它们可以从代码中访问,例如:

代码语言:javascript
复制
>>> def spam(a: 'eggs') -> 'ni!':
...     pass
...
>>> spam.__annotations__
{'a': 'eggs', 'return': 'ni!'}

尽管同样的行为可以很容易地通过装饰器实现,比如:

代码语言:javascript
复制
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已经可以做注解所做的事情,那么为什么函数注解需要专用的语法呢?

编辑:我将对我的问题做一点扩展,因为它的意思已经被证明是稍微不清楚的。

我特别问这个问题是关于函数注释的,而不是装饰器的。

代码语言:javascript
复制
@decorator
def spam():
    pass

是的缩写

代码语言:javascript
复制
def spam():
    pass
spam = decorator(spam)

和方法调用,其中

代码语言:javascript
复制
self.method(param)

是的缩写

代码语言:javascript
复制
Class.method(self, param)

有了这两个简写的语法快捷键,它们的含义就不能。我不是在问,既然已经有了替代方案,为什么需要这样的捷径;这是一个可读性问题。函数注释与这两个快捷键略有不同,因为

代码语言:javascript
复制
def spam() -> int:
    pass

代码语言:javascript
复制
def spam() -> 'integer':
    pass

可能与人类具有相同的含义,但不会与计算机具有相同的含义。即使程序员知道注释应该定义什么,对于注释如何定义它也没有达成一致的定义。此外,注释不会影响功能,因此没有一致性的要求。

下面是我修改后的问题:

当函数注解提供了一种可改变且可能不一致的方式来访问已经存在的语言功能时,为什么它们需要专用的语法呢?为什么没有关于如何使用注释的强制定义,而它们可以用于什么方面有一个完美的定义(PEP 3107)?

EN

回答 3

Stack Overflow用户

发布于 2012-08-31 02:53:31

您链接到的PEP 3107似乎在其“基本原理”部分为您的问题提供了答案:

基本原理

由于Python2.x系列缺乏注释函数参数和返回值的标准方法,因此出现了各种工具和库来填补这一空白。有些利用了“PEP318”中引入的装饰器,而另一些则解析函数的文档字符串,查找那里的注释。

这个PEP旨在提供一种单一的、标准的方式来指定这些信息,减少由于机制和语法的巨大差异而造成的混乱,直到现在。

票数 6
EN

Stack Overflow用户

发布于 2012-08-31 02:54:17

装饰器语法的意义是什么?它不允许你做任何你以前不能做的事情:

代码语言:javascript
复制
@staticmethod
def foo():
    pass

就是

代码语言:javascript
复制
def foo():
    pass
foo = staticmethod(foo)

但是装饰器的语法更好。

在这两个中,哪一个更好:

代码语言:javascript
复制
@param(a='eggs')
@return_('ni!')
def spam(a):
    pass

def spam(a: 'eggs') -> 'ni!':
    pass

意见可能不同,但我认为第二种更好。

票数 6
EN

Stack Overflow用户

发布于 2018-07-12 03:23:52

我非常喜欢类型注解,因为它们可以被我的集成开发环境PyCharm识别。通过注释类型,PyCharm将在我编码时知道变量的类型。这使我可以在可能不完全记住其名称的类中找到所需的函数,并在不实际查看该类的代码/文档的情况下查找它们。

正如您所说的,与注释不同,类型注释可以从代码中访问。这是一笔巨大的交易,因为它允许创建确保类型的类,并基于成员指定的类型提供其他功能。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12203468

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档