Are the keys of a kwargs argument to Python function guaranteed to be type string?

后端 未结 3 1510
长情又很酷
长情又很酷 2020-12-20 21:01
def func(**kwargs):
   for key, value in kwargs.items():
      # Is key always going to be a string?
      # Could it have spaces?
      pass

Two qu

相关标签:
3条回答
  • 2020-12-20 21:24

    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.)

    0 讨论(0)
  • 2020-12-20 21:33

    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
    
    0 讨论(0)
  • 2020-12-20 21:46

    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 of POSITIONAL_ONLY parameters, which can have it set to None.)

    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 letters A through Z, the underscore _ and, except for the first character, the digits 0 through 9. ...

    0 讨论(0)
提交回复
热议问题