问题
def func(**kwargs):
for key, value in kwargs.items():
# Is key always going to be a string?
# Could it have spaces?
pass
Hey Guys,
Two questions about kwargs in Python.
- Is every key of kwargs guaranteed to be of type str? If so, I can avoid type checking.
- If #1 is true, would every key be guaranteed to not have spaces?
Thanks,
回答1:
A keyword argument passed directly must be a valid Python identifier, and yes it will always be treated as strings. Anything else is a SyntaxError
.
f(foo=1) # Works
f($=1) # Fails
f(1=1) # Fails
Although, you can also give keyword arguments through unpacking. In this case, your keyword arguments must be strings still, but they can take any format.
Let's define a dummy function to test this.
def f(**kwargs):
print(kwargs)
A keyword argument can contain a space or be a string of digits. It can even contain special characters.
f(**{"hello world": 'foo'}) # prints {'hello world': 'foo'}
f(**{"1": 'foo'}) # prints {'1': 'foo'}
f(**{"$": 'foo'}) # prints {'$': 'foo'}
A keyword argument must be a string. Anything else is a TypeError
.
f(**{1: 'foo'}) # TypeError: f() keywords must be strings
f(**{b'foo': 1}) # TypeError: f() keywords must be strings
回答2:
The keywords
in kwargs
should follow the rules of variable names, full_name
is a valid variable name (and a valid keyword
), full name
is not a valid variable name (and not a valid keyword
).
From PEP 362 -- Function Signature Object:
A Parameter object has the following public attributes and methods:
name : str
- The name of the parameter as a string. Must be a valid python identifier name (with the exception ofPOSITIONAL_ONLY
parameters, which can have it set toNone
.)
And, from the Docs:
2.3. Identifiers and keywords:
... Within the ASCII range (U+0001..U+007F), the valid characters for identifiers are the same as in Python 2.x: the uppercase and lowercase lettersA
throughZ
, the underscore_
and, except for the first character, the digits0
through9
. ...
回答3:
Others have already covered the practical side of this, but I wondered if the documentation actually made any guarantees about keyword dictionaries' types.
The documentation on call semantics does not specifically say keyword arguments will have type str
in the dictionary.
This is all that the documentation says about the type of the value of keyword arguments passed to a parameter declared with **
:
a dictionary containing the excess keyword arguments (using the keywords as keys and the argument values as corresponding values), or a (new) empty dictionary
So, theoretically, it appears that the documentation allows you to recieve keyword arguments as bytes
, but this does not occur in any current implementation of Python 3.
(For Python 2, the same holds, but for unicode
instead of bytes
.)
来源:https://stackoverflow.com/questions/57897649/are-the-keys-of-a-kwargs-argument-to-python-function-guaranteed-to-be-type-strin