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.