Получение имен полей с помощью Python - PullRequest
3 голосов
/ 28 апреля 2011

Можно ли рефлекторно получить имя поля в Python (3.2)?

См. Следующий пример:

class Something:
    def __init__(self):
        self.x = 1

    def validate():
        return validator.max(self.x, 10)

validator.max(self.x, 10) должен выдать сообщение об ошибке, содержащее имя поля x в виде строки (в данном случае "x").

Ответы [ 3 ]

5 голосов
/ 28 апреля 2011

Вы должны передать имя атрибута в виде строки

def validate():
    return validator.max(self, "x", 10)

тогда validator.max может выглядеть следующим образом

def max(ob, attr, max_value):
    val = getattr(ob, attr)    # val would be self.x now
    ...
2 голосов
/ 28 апреля 2011

В 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 будет правильно находить унаследованные члены.

2 голосов
/ 28 апреля 2011

Вряд ли.Вещи могут даже не иметь имен - что:

validator.max(3,10)

должен делать?

Передать имя и значение, если вы хотите, чтобы оно выводилось:

validator.max(self.x,10,"x")

каким бы ни был validator.max, ему нужен другой аргумент, или, если он встроенный, вам нужно обернуть его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...