Why does not kwargs accept a keyword? [keyword can not be an expression]

1

In python there is the kwargs , which makes things much easier , when I need to name parameters. define what are the attributes of an element that I will create with this function I have a function where the second parameter I use a kwargs. However, when I pass the keyword class per parameter an error is generated.

Example:

create_element_tag('tag', 'class'='x')]

Output:

  

keyword can not be an expression

Example:

create_element_tag('tag', class='x')

Output:

  

SyntaxError: invalid syntax

But I really need an attribute whose index contains that name.

How could I solve this problem in python ?

    
asked by anonymous 15.01.2016 / 16:04

1 answer

2

It is not possible to understand what you are calling "kwargs" - but in Python it is possible to specify optional arguments in a function and select arguments by keyword - this is what we call "keyword arguments":

def conectar(host, porta=80, timeout=None):
    # [corpo da função]

conectar("http://...", timeout=10)

In the above example, the default value of port (80) that is in the function definition is used, and the timeout value is sent as the second parameter - specifying this "keyword argument" in the function call. "From what I understand, this is what you're calling" kwargs. "

At no point, in Python, you can write a keyword that is a "statement" as a variable name - or as a parameter name. So, you can not have arguments named def , for , while or class . This is a syntax error. Ex.:

def funcao(while=1):
   pass

class is the key word used to define classes - so it is reserved. Some of Python's built-in names can be redefined, and used as variable names at will - they usually denote classes or functions, which however they have, do not have a special language handling: list , id , type , etc ...

Now - Python does have a mechanism that allows parameters for a function to be passed as data, rather than fixed in code: prefixing the name of a parameter with two asterisks in the definition of a function, causes any unknown parameters are received within a dictionary, which is assigned to that parameter. In general, the name of this dictionary is kwargs or kw - but this is just a convention.

In [1]: def ve_parametros(**kw):
   ...:     print(kw)
   ...:     

In [2]: ve_parametros(a=5, b=6)
{'b': 6, 'a': 5}
Note that the "a" and "b" parameters used in the function call become "kw" dictionary keys - which can be treated as common strings within the function.

This does not yet allow you to use keywords in the function call -

In [3]: ve_parametros(class=5)                                                                                                                                                    
  File "<ipython-input-3-62829ca1a227>", line 1                                                                                                                                   
    ve_parametros(class=5)                                                                                                                                                        
                      ^                                                                                                                                                           
SyntaxError: invalid syntax     

However, there is the analogue mechanism - if you call a function with two asterisks in a function call, the dictionary keys and values will be used as keyword arguments within that function:

In [4]: def recebe_parametros(a, b, c):
   ...:     print ("a: {}, b: {}, c: {}".format(a, b, c))
   ...:                                                                                                                                                                           

In [5]: params = {"c": 3, "b": 2, "a": 1}

In [6]: recebe_parametros(**params)                                                                                                                                               
a: 1, b: 2, c: 3  

So if you use ** both to create the parameters of your function and to get them, you can have keyword-named parameters - which will be treated exclusively as strings (but can never be fixed in code ):

In [8]: def reserved_params(**kw):
...:     if "class" in kw:
...:         print("Recebi o parâmetro 'class': {}".format(kw["class"]))
...:         

In [9]: reserved_params(**{"class": "parametro proibido"})
Recebi o parâmetro 'class': parametro proibido

If you need the name class because your function, for example, is outputting a html snippet, and the function already accepts variable parameters, that solution should be enough - just use the word "class" as the key of a dictionary in the call to it. If it is a popular library that html mounts in this way, it is more likely that it will accept a class-like name that is automatically converted to class in the function output - names like klass , class_ or cls are usually used. I recommend that you consult the html generator documentation that, it seems to me, you are using.

And finally, this way of passing keywords is not the best solution: in the case that automatic parameters are used, in general one should not try to use keywords as name of variables: the resources of passage and reception of dynamically per-dictionary parameters lend themselves to a myriad of other things - and since Python is not a lot of exceptions, you can do that. Because if the parameter name is passed as a string in a dictionary and consumed as a string within the function, the language has no reason to treat it as a variable name at an intermediate stage, and thus throw a syntax: you can use keywords as in the examples above, although this is not the purpose of the variable parameters.

    
16.01.2016 / 02:35