Следующие решения vars(self).update(kwargs)
или self.__dict__.update(**kwargs)
не являются надежными, поскольку пользователь может ввести любой словарь без сообщений об ошибках.Если мне нужно проверить, чтобы пользователь вставил следующую подпись («a1», «a2», «a3», «a4», «a5»), решение не работает.Более того, пользователь должен иметь возможность использовать объект, передавая «позиционные параметры» или «параметры пар kay-value».
Поэтому я предлагаю следующее решение с использованием метакласса.
from inspect import Parameter, Signature
class StructMeta(type):
def __new__(cls, name, bases, dict):
clsobj = super().__new__(cls, name, bases, dict)
sig = cls.make_signature(clsobj._fields)
setattr(clsobj, '__signature__', sig)
return clsobj
def make_signature(names):
return Signature(
Parameter(v, Parameter.POSITIONAL_OR_KEYWORD) for v in names
)
class Structure(metaclass = StructMeta):
_fields = []
def __init__(self, *args, **kwargs):
bond = self.__signature__.bind(*args, **kwargs)
for name, val in bond.arguments.items():
setattr(self, name, val)
if __name__ == 'main':
class A(Structure):
_fields = ['a1', 'a2']
if __name__ == '__main__':
a = A(a1 = 1, a2 = 2)
print(vars(a))
a = A(**{a1: 1, a2: 2})
print(vars(a))