Is is safe to use a function accepts kwargs keyword arguments that are not identifiers?

前端 未结 1 1354
自闭症患者
自闭症患者 2020-12-19 08:30

In Python, is it safe to give keyword arguments that are not Python identifiers to a function? Here is an example:

>>> \'{x-y}\'.format(**{         


        
相关标签:
1条回答
  • 2020-12-19 08:57

    First of all: the **{...} call convention with non-identifier names only works if the called function has a **kw argument to receive them, as it too cannot define explicit keyword arguments that are not valid identifiers.

    I'd say that the keyword_arguments grammar only applies to the parser of the source code, and cannot ever be seen as a functional restriction on the contents of the **expression result. The functional description below does not restrict the keys of the dictionary explicitly, nor does the function definition documentation.

    Instead, since the grammar allows an expression, and the functional spec states that that should resolve to a mapping the contents of which are treated as additional keyword arguments, it is clear (to me) that there are no restrictions on the keys at all, beyond the normal ones applicable to Python dictionaries (keys must be immutable). You can pass in tuple or numeric keys for all Python cares. The functional spec states how the contents are treated, not that the contents must fit a certain format.

    So, in my opinion the functional spec would have to explicitly restrict the keys in the **expression dictionary to disallow what you are doing, because the grammar certainly does not. Changing that would be a huge backwards-incompatible change, and is not likely to ever be added.

    Note that even though the spec doesn't mention any restrictions on the keys of the dictionary, CPython does:

    >>> def f(*args, **kw): print args, kw
    ... 
    >>> f(**{1: 2})
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: f() keywords must be strings
    

    This is a restriction made by the python interpreter when invoking code objects (user defined functions). The reason why is explained in the source code right after the part that raises the above exception:

    /* Speed hack: do raw pointer compares. As names are
       normally interned this should almost always hit. */
    

    By restricting keywords to strings a speed optimisation is possible.

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