Один из способов, который был бы более общим, чем подход Django, __slots__
и , доступные в Python 2, - это метакласс:
class OrderedTypeMeta(type):
def __new__(mcls, clsname, bases, clsdict):
attrs = clsdict.get('_attrs_', [])
attrnames = []
for name, value in attrs:
clsdict[name] = value
attrnames.append(name)
clsdict['_attrs_'] = attrnames
return super(OrderedTypeMeta, mcls).__new__(mcls, clsname, bases, clsdict)
class User(DataStructure):
__metaclass__ = OrderedTypeMeta
_attrs_ = (('name', StringValue()),
('password', StringValue()),
('age', IntegerValue()))
Я говорю, что он более общий, чем способ Djangoпоскольку вам не нужно, чтобы атрибуты были экземплярами определенного класса, подойдет любое значение.Он также более общий, чем __slots__
, потому что вы все равно сможете назначать атрибуты экземплярам классов (хотя это может и не понадобиться: в этом случае я бы предпочел __slots__
).В python3 я бы предпочел __prepare__
.
Основным недостатком этого, помимо того, что это некрасиво, является то, что он не будет работать с наследованием.Было бы не слишком сложно извлечь __attrs__
из базовых классов и расширить его, вместо того, чтобы устанавливать его в пустой список.