I have this small bit of code in a file ( small.py
):
def async(foo):
pass
def bar(foo):
pass
async def bar(foo):
return None
async def async(foo):
return None
When I do python3.6 small.py
it issues this complaint:
File "small.py", line 7
async def async(foo):
^
SyntaxError: invalid syntax
If I comment out the last two lines of the file it works fine.
What's going on here? Why is it perfectly fine to have def async
but not OK to have async def async
?
Additionally, I have this file ( small2.py
):
def async(foo):
pass
def bar(foo):
return async(foo)
async def baz(foo):
return async(foo)
And when I do python2.6 small2.py
I get this:
File "small2.py", line 8
return async(foo)
^
But if I change baz
to call bar
instead of async
it works just fine. How do I call async
inside of baz
?
Well, I was hoping someone would answer this, but nobody has with the correct answer.
The problem is that in Python 3.5 and 3.6, the words async
and await
are keywords, but only sometimes. Other times they play the role of identifiers.
The only time await
is a keyword is inside of a function declared async def
. And the only time async
is a keyword is just before def
or inside an async def
function. Of course, in the async def async(foo)
case, the second use of async
is an attempt to use it as an identifier inside an async def
and so it fails because there, it's a keyword.
This is kind of weird, as all other keywords are always keywords everywhere. For example, you can't use while
as an identifier ever.
This situation will change in Python 3.7 and both async
and await
will be keywords everywhere, just like every other keyword.
It's this way in Python 3.5 and 3.6 because they didn't want to just spring a new keyword on everybody right away. When you add a new keyword, lots of people might have identifiers that have the same name as your new keyword, and so those identifiers become illegal and people have to change their code and may get all kinds of weird errors until they do.
The answer to how to use an identifier named async
or await
inside of an async def
function is that you don't. You have to use getattr
or alias the object the identifier refers to or otherwise arrange it so that you do not use the words async
or await
in your async def
function as anything other than the keywords they are there.
This is described a little, though the implications are not really thoroughly worked through, in the transition plan section of PEP 492 .
As a side note, redefining names in Python is just fine. One might better think of def foo
as foo = lambda
(except that lambdas are limited to single expressions in Python). So, assigning a new function value to foo
causes no problems and is simple and well defined.
The reason for the error is you are using the reserved keyword async as your function name so when ever you try to invoke it. It tries to call the async keyword rather than the function which has been overridden by the same.
To demonstrate this more clearly in a directory create two files one with name requests.py
another one as test.py.
Now if you use import requests
( python library ) and use any of it's methods in test.py
it ll throw you an error. Because the file requests.py
overrides the library requests
.
The same scenario happens here. You have declared a function with name async
. Also you have declared a async method later which overrides the method with name async . Hence whenever you call async it tries to call async method. Since async
is a reserved keyword and no longer a function which has been overridden, it reports error. To fix this change the function name from async to something else.
'''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
Also the same happens with the later case of your question.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.