There is data binding in Python

1

Hello, guys. You know some kind of data binding in Python that you commonly have in Java frameworks, such as JSF, Spring, and so on. I have already used Flask and Django and I have not seen a similar feature in both, so I have to attribute attribute to my classes. I do not know if this is really common in the Python world, because if it is not, then I was very badly accustomed in Java rsrs ... Thanks in advance.

It would be an automatic way of setting attributes in a class, for example:

class Endereco(object):
  logradouro = None
  numero = None
class Pessoa(object):
  nome = None
  idade = None
  endereco = Endereco

params = { "nome": "Lol", "idade": 30, "endereco": { "logradouro": "rua longe pra cacete", "numero": "300" } }

p = binding(params, Pessoa) // método mágico que cria um o objeto do tipo Pessoa a partir do mapa
    
asked by anonymous 27.04.2017 / 00:59

1 answer

0

It does not exist in the default library - but it's relatively easy to do by putting the code for it in your base class - and calling the constructor of that class.

Unfortunately this leaves many ways to do this - right now, in the list of e-mails python-ideas a possible inclusion of a standardized way of doing this is debated (after accessing the link, click% with% at the bottom of the page to see all e-mails) discussion, u am in favor of a decorator - and by no means a new syntax, as the original author of the thread suggests.

But a base class is even simpler than a decorator - So - Python allows a function to receive any number of named parameters, without knowing their names beforehand - just prefix a parameter with thread on the assumption of function the various parameters are impaled as a dictionary. Similarly, when calling a function, prefixing an object of type ** (like a dictionary) with mapping unpacks all dictionary items as parameters for a function.

This allows us to have in the method ** of the base class a code that receives all the parameters, verify that the attribute exists in the class, and, if it exists, bind it. From toast, you can even implement type-checking, checking if a parameter is a subclass of the declared parameter in the class:

class Base:
    def __init__(self, **kwargs):
        cls = self.__class__
        # itera em uma cópia dos items do dicionário, 
        # permitindo que ele seja alterado durante o "for":
        for name, value in list(kwargs.items()):
            # Verifica se o parâmetro existe na própria classe,
            # caso contrário, mantem o mesmo no dicionário.
            if not hasattr(cls, name):
                continue
            if not isinstance(value, getattr(cls, name)):
                raise TypeError("Incorrect parameter type passed for {}. An '{}' was expected.".format(
                    cls.__name__, getattr(cls, name).__name__))
            setattr(self, name, value)
            del kwargs[name]


class Pessoa(Base):
    nome = str
    idade = int
    endereco = dict

And, in interactive mode:

In [104]: params = { "nome": "Lol", "idade": 30, "endereco": { "logradouro": "rua longe pra cacete", "numero": "300" } }
     ...: 

In [105]: p  = Pessoa(**params)

In [106]: p.nome, p.idade, p.endereco
Out[106]: ('Lol', 30, {'logradouro': 'rua longe pra cacete', 'numero': '300'})

In [107]: params["idade"] = "muito velho"

In [108]: p2 = Pessoa(**params)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
(...)
TypeError: Incorrect parameter type passed for Pessoa. An 'int' was expected.
    
28.04.2017 / 02:39