It doesn’t exist in the standard library - but it’s something relatively easy to do by placing 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, on the E-more list python-ideas
is debating a possible inclusion of a standardized way of doing this (after accessing the link, click on thread
at the bottom of the page to see all E-Oover) - in this discussion, u am in favor of a developer - and in no way a new syntax, as the original thread author suggests.
But a base class is even simpler than a developer - so - Python allows a function to receive any number of named parameters, without knowing their names beforehand - just prefix a parameter with **
in the asymmetry of the function the various parameters are paired as a dictionary.
Similarly, in calling a function, prefix an object of the type mapping
(as a dictionary) with **
unpack all dictionary items as parameters for a function.
This allows us to have in the method __init__
of the base class a code that receives all parameters, check if the attribute exists in the class, and, if it exists, make the Binding of it. As a gift, you can even implement type-checking by checking whether a parameter is a sub-class of the parameter declared 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.
There’s a better way to detail what that would be Binding desiring?
– Woss
ready! partner updated the post to better explain my question
– Mikael Santos
I believe that there is nothing of this kind, not least because Python is not strongly typed, like Java. There is a function that can do this, but I believe that manually is more appropriate. Here There is a code that I made very shallow that does what it wants, but I reaffirm, I did it superficially only for testing. Maybe you can build on it and do something interesting.
– Woss
@Andersoncarloswoss thank you so much for your kindness to write an example, it will already be of great help to me
– Mikael Santos