开发者

formencode nesting custom validators within schema

I want to nest my custom valid开发者_如何学Pythonators within my schema, like this:

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())

However, it seems to think that MyValidator and MyOtherValidator are fields b/c it's form_errors contain:

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

If I don't nest them, they seem fine. What am I missing?


My advice is: you should move the FancyValidator subclass definitions to global scope, either (1) in the same module just before the definition of the Schema in which they're used, or (2) in a separate module for greater reuse. Unless there is a specific reason why nesting is required, a few extra class names in the module namespace shouldn't hurt.

For example:

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)

Result:

{'field_foo': 'x_foo', 'field_bar': 'y_bar'}


In python, anything that you define in your class is a field. Be it static variables, variables set with self, methods or classes. If you want to "hide" the classes, or make them "less public", as is probably the right wording in the python dictionary, you should start their names with __.

>>> 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']

As you can see, there is a loophole for this kind of privacy, but most automatic tools will recognize that you are trying to make something private.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜