Я хочу проверить два поля объекта после инициализации.Я использую attrs для определения мета-класса PropertyMeta, а затем использую PropertyMeta в другом классе PropertyDescriptor.
class PropertyMeta(type):
EXPECTED_VARS = ('PROPERTIES', 'PROPERTY_DEFAULTS',
'PROPERTY_VALIDATORS', 'PROPERTY_CONVERTERS')
@classmethod
def _get_attrib(mcs, property_name, attrs):
kwargs = {}
if property_name in attrs['PROPERTY_DEFAULTS']:
kwargs.update(default=attrs['PROPERTY_DEFAULTS'][property_name])
return attr.attrib(**kwargs)
def __new__(mcs, name, bases, attrs):
if 'PROPERTIES' not in attrs:
attrs['PROPERTIES'] = []
else:
# For the defaults, converters, and validators ensure that extra attributes are not passed.
# If they are defined, set the default value as an empty dict.
for expected_attr in mcs.EXPECTED_VARS:
if expected_attr == 'PROPERTIES':
continue
if expected_attr in attrs:
for arg in attrs[expected_attr]:
if arg not in attrs['PROPERTIES']:
raise ValueError(
"Found a '%s' for an attribute '%s' in '%s' that doesn't belong to 'PROPERTIES';"
" ('PROPERTIES': %r, '%s': %r)" %
(arg, expected_attr, name,
attrs['PROPERTIES'], expected_attr, attrs[expected_attr])
)
else:
attrs[expected_attr] = {}
# Create class from attr with all required attributes. This will set properties in same format as specified
# by attr.
new_cls = attr.make_class(name,
{property_name: mcs._get_attrib(property_name, attrs) for property_name in
attrs['PROPERTIES']})
# Merge the attr class to present class.
return super(PropertyMeta, mcs).__new__(mcs, name, (new_cls,) + bases, attrs)
@six.add_metaclass(PropertyMeta)
class PropertyDescriptor(object):
def __init__(self):
print("Not getting called.")
def __setattr__(self, property_name, property_value):
# Convert properties to appropriate types if specified.
if property_name in self.PROPERTY_CONVERTERS:
property_value = self.PROPERTY_CONVERTERS[property_name](
property_value)
# Validate property values.
if property_name in self.PROPERTY_VALIDATORS:
try:
validator = self.PROPERTY_VALIDATORS[property_name]
validator(self, property_name, property_value)
except Exception as err:
raise err
super(PropertyDescriptor, self).__setattr__(property_name, property_value)
Я пытаюсь создать экземпляр объекта, используя PropertyDescriptor в качестве базового класса.Всякий раз, когда создается экземпляр моего объекта, init PropertyDescriptor не вызывается.
Пример наследования от PropertyDescriptor.
class Example(PropertyDescriptor):
def __init__(self, **kwargs):
super(A, self).__init__(**kwargs)
print(self.__dict__)
a = Example(start_time=1, end_time=2)
init класса Example вызывается.Поэтому я могу проверить поля, которые start_time всегда меньше, чем end_time
Два вопроса:
- Я хочу убедиться, что start_time всегда меньше, чем end_time.Есть ли лучший способ добиться этого?
- Почему init не вызывается в PropertyDescriptor?