Как использовать attr.validators.optional
В соответствии с документацией attrs необязательные атрибуты должны быть объявлены следующим образом:
>>> @attr.s
... class C(object):
... x = attr.ib(validator=attr.validators.optional(attr.validators.instance_of(int)))
>>> C(42)
C(x=42)
>>> C("42")
Traceback (most recent call last):
...
TypeError: ("'x' must be <type 'int'> (got '42' that is a <type 'str'>).", Attribute(name='x', default=NOTHING, validator=<instance_of validator for type <type 'int'>>, type=None, kw_only=False), <type 'int'>, '42')
>>> C(None)
C(x=None)
Однако, когда я пытаюсь использовать необязательные атрибуты, я получаю следующие результаты:
python
Python 2.7.15 (default, Jul 23 2018, 21:27:06)
[GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.2)] on darwin
класс с обязательным атрибутом
определение класса
>>> import attr
>>> @attr.s
... class Result(object):
... log = attr.ib(validator=attr.validators.instance_of(str))
...
Создание класса
с отсутствующим атрибутом>>> test = Result()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __init__() takes exactly 2 arguments (1 given)
Хорошо
с неверным типом>>> test = Result(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<attrs generated init 086c7a4a2a56d2e9002255c4e881a832c6bc5360>", line 4, in __init__
File "/.../.venv/lib/python2.7/site-packages/attr/validators.py", line 32, in __call__
value,
TypeError: ("'log' must be <type 'str'> (got 1 that is a <type 'int'>).", Attribute(name='log', default=NOTHING, validator=<instance_of validator for type <type 'str'>>, repr=True, cmp=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False), <type 'str'>, 1)
Хорошо
с правильным типом>>> test = Result('aaa')
>>> test.log
'aaa'
Хорошо
класс с необязательным атрибутом
определение класса
>>> import attr
>>> @attr.s
... class Result(object):
... log = attr.ib(validator=attr.validators.optional(attr.validators.instance_of(str)))
...
Создание класса
с отсутствующим атрибутом>>> test = Result()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __init__() takes exactly 2 arguments (1 given)
KO
с неверным типом>>> test = Result(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<attrs generated init 7e2ff957cec78e81193f38c89e2f4eb2ff2dad4e>", line 4, in __init__
File "/.../.venv/lib/python2.7/site-packages/attr/validators.py", line 106, in __call__
self.validator(inst, attr, value)
File "/.../.venv/lib/python2.7/site-packages/attr/validators.py", line 32, in __call__
value,
TypeError: ("'log' must be <type 'str'> (got 1 that is a <type 'int'>).", Attribute(name='log', default=NOTHING, validator=<optional validator for <instance_of validator for type <type 'str'>> or None>, repr=True, cmp=True, hash=None, init=True, metadata=mappingproxy({}), type=None, converter=None, kw_only=False), <type 'str'>, 1)
Хорошо
с правильным типом>>> test = Result('aaa')
>>> test.log
'aaa'
Хорошо
Что я делаю не так, чтобы использовать дополнительные атрибуты? Где мое заблуждение?
1 ответ
Правильное определение класса:
>>> @attr.s
... class Result(object):
... log = attr.ib(default=None, validator=attr.validators.optional(attr.validators.instance_of(str)))