我在文件 (small.py) 中有这么一小段代码:
def async(foo):
pass
def bar(foo):
pass
async def bar(foo):
return None
async def async(foo):
return None
当我执行 python3.6 small.py 时,它发出此投诉:
File "small.py", line 7
async def async(foo):
^
SyntaxError: invalid syntax
如果我注释掉文件的最后两行,它就可以正常工作。
这是怎么回事?为什么使用 def async 完全没问题,但使用 async def async 却不行?
另外,我有这个文件(small2.py):
def async(foo):
pass
def bar(foo):
return async(foo)
async def baz(foo):
return async(foo)
当我执行 python2.6 small2.py 时,我得到了这个:
File "small2.py", line 8
return async(foo)
^
但是,如果我将 baz 更改为调用 bar 而不是 async,它就可以正常工作。如何在 baz 中调用 async?
请您参考如下方法:
好吧,我希望有人能回答这个问题,但没有人给出正确答案。
问题是在 Python 3.5 和 3.6 中,单词 async和 await是关键字,但只是有时。其他时候,它们扮演标识符的角色。
唯一一次await是关键字在声明的函数内部 async def .而且是唯一一次async是关键字就在 def 之前或在 async def 内功能。当然,在async def async(foo)案例,第二次使用async试图将其用作 async def 中的标识符所以它失败了,因为那里有一个关键字。
这有点奇怪,因为所有其他关键字在任何地方都是关键字。例如,您不能使用 while作为标识符。
这种情况将在 Python 3.7 和两者中改变 async和 await将是无处不在的关键字,就像所有其他关键字一样。
在 Python 3.5 和 3.6 中就是这样,因为他们不想马上给每个人都弹出一个新关键字。当你添加一个新关键字时,很多人可能拥有与你的新关键字同名的标识符,因此这些标识符变得非法,人们不得不更改他们的代码并且可能会遇到各种奇怪的错误,直到他们这样做。
关于如何使用名为 async 的标识符的答案或 await async def 内部功能是你没有。你必须使用 getattr或别名标识符所指的对象或以其他方式安排它,以便您不使用单词 async或 await在你的async def与它们所在的关键字以外的任何东西一样起作用。
在 transition plan section of PEP 492 中对此进行了一些描述,但其中的含义并未真正彻底解决。 .
附带说明一下,在 Python 中重新定义名称就好了。人们可能会更好地想到 def foo作为foo = lambda (除了 lambda 仅限于 Python 中的单个表达式)。因此,为 foo 分配一个新的函数值不会导致任何问题,并且简单且定义明确。
