пользовательские валидаторы вложенных кодов в схеме - PullRequest
2 голосов
/ 07 мая 2011

Я хочу вложить свои собственные валидаторы в мою схему, например:

MySchema(Schema):
    class MyValidator(validators.FancyValidator):
        def _to_python(self, value, state):
            ...
    class MyOtherValidator(validators.FancyValidator):
        def _to_python(self, value, state):
            ...

    field_foo = All(validators.NotEmpty(),
                    MyValidator())
    field_bar = All(validators.NotEmpty(),
                    MyOtherValidator())

Тем не менее, кажется, что MyValidator и MyOtherValidator являются полями, потому что form_errors содержит:

{ 
  'MyValidator': 'Missing value',
  'MyOtherValidator': 'Missing value'
}

Если я их не вкладываю, они кажутся нормальными. Чего мне не хватает?

Ответы [ 2 ]

2 голосов
/ 19 мая 2011

Мой совет: вы должны переместить определения подкласса FancyValidator в глобальную область, либо (1) в том же модуле непосредственно перед определением Schema, в котором они используются, либо (2) в отдельный модуль для большего повторного использования. Если нет конкретной причины, по которой требуется вложение, несколько дополнительных имен классов в пространстве имен модуля не должны повредить.

Например:

from formencode import All, FancyValidator, Schema, validators

class MyValidator(FancyValidator):
    def _to_python(self, value, state):
        return value + '_foo'

class MyOtherValidator(FancyValidator):
    def _to_python(self, value, state):
        return value + '_bar'

class MySchema(Schema):
    field_foo = All(validators.NotEmpty(), MyValidator())
    field_bar = All(validators.NotEmpty(), MyOtherValidator())

print MySchema().to_python({'field_foo': 'x', 'field_bar': 'y'}, None)

Результат:

{'field_foo': 'x_foo', 'field_bar': 'y_bar'}
0 голосов
/ 17 мая 2011

В Python все, что вы определяете в своем классе, является полем.Будь то статические переменные, переменные, установленные с помощью self, методы или классы.Если вы хотите «скрыть» классы или сделать их «менее общедоступными», как, вероятно, является правильной формулировкой в ​​словаре python, вы должны начинать их имена с __.

>>> dir(X())
['A', '_B', '_X__C', '__doc__', '__module__']
>>> class X:
...     class A: pass
...     class __B: pass
...     c = 0
...     __d = 1
... 
>>> dir(X())
['A', '_X__B', '_X__d', '__doc__', '__module__', 'c']

. Как вы можете видеть,Существует лазейка для такого рода конфиденциальности, но большинство автоматических инструментов распознают, что вы пытаетесь сделать что-то личное.

...