[英]Why does this weird syntax oddity involving async exist in Python?
我在文件( 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
更改为call 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 def
函数中使用名为async
或await
的标识符的答案是,您不会这样做。 您必须使用标识符所引用的对象的getattr
或别名,或以其他方式对其进行排列,以便不要在async def
函数中将单词async
或await
用作其附近的关键字。
尽管在PEP 492的过渡计划部分中并未真正彻底地阐明其含义,但对此进行了一些描述。
附带说明一下,在Python中重新定义名称就可以了。 最好将def foo
视为foo = lambda
(除了lambda仅限于Python中的单个表达式)。 因此,为foo
分配新的函数值不会造成任何问题,并且操作简单且定义明确。
错误的原因是您使用保留关键字async作为函数名称,因此无论何时尝试调用它。 它尝试调用async关键字,而不是调用已被该关键字覆盖的函数。
为了在目录中更清楚地说明这一点,请创建两个文件,一个文件名为requests.py
另一个文件名为test.py.
现在,如果您使用import requests
( python库 )并在test.py
使用它的任何方法,它将抛出错误。 因为文件requests.py
会覆盖库requests
。
同样的情况在这里发生。 您已使用名称async
声明了一个函数。 另外,您稍后还声明了一个异步方法,该方法将使用名称async覆盖该方法。 因此,无论何时调用异步,它都会尝试调用异步方法。 由于async
是保留关键字 ,不再是已被覆盖的函数,因此它将报告错误。 要解决此问题,请将函数名称从异步更改为其他名称。
'''def async(foo): #overrides async coroutine hence now async refers to this function.
pass'''
def asyn(foo):
pass
def bar(foo):
pass
async def bar(foo):
return None
async def asyn(foo): # aync refers to above commented method in your code rather than coroutine.
return None
您的问题的后一种情况也是如此。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.