В Python выражение self.x
является просто текущим значением этого члена, и поэтому информация о том, что значение исходит от объекта, теряется.
Однако вы можете переместить логику проверки на более высокий уровень (базовый класс) и заставить ее работать над всем объектом. При таком подходе валидатор «имя» будет известен функции validate и может использоваться для сообщения об ошибке:
class ValidatedObject:
def validate(self):
for name in dir(self):
if (name.startswith("validate_") and # Is a validator
not getattr(self, name)()): # and failed
raise RuntimeError("%s: %s" %
(name, getattr(self, name).__doc__))
class Something(ValidatedObject):
def __init__(self, x, y):
self.x = x
self.y = y
def validate_x(self):
"Horizontal position shouldn't be that big"
return self.x < 10
def validate_y(self):
"Vertical position must be neither too low nor too high"
return 20 <= self.y <= 30
def validate_sum(self):
"The position must be on the prescribed line"
return self.x + self.y == 25
class Something2(Something):
def validate_sum(self):
return True
Something(3, 22).validate() # Ok
Something2(5, 30).validate() # Ok (derived class relaxed checks)
print "About to crash...."
Something2(5, 31).validate() # Not ok (Y is too high - inherited check)
Обратите внимание, что отключение проверки в производном классе нелогично с точки зрения IS-A, здесь приведен пример, показывающий, что dir
будет правильно находить унаследованные члены.