[英]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.