我是python的新手。我正在尝试使用必需的验证器创建配置类。在下面的代码片段中,使用python类和类实例访问变量'a'返回一个不同的值。无论这是一个适当的设计,还是仅应在类构造函数中初始化var'a',并在setter方法中进行验证。
class IntField:
def __get__(self, instance, owner):
if instance is None:
return self
return instance.__dict__[self.name]
def __set__(self, instance, value):
if not isinstance(value, int):
raise ValueError('expecting integer')
instance.__dict__[self.name] = value
def __set_name__(self, owner, name):
self.name = name
class DefaultConfig:
a = IntField()
def __init__(self):
self.a = 2
print(DefaultConfig.a)
print(DefaultConfig().a)
输出:
<__main__.IntField object at 0x10c34b550>
2
答案 0 :(得分:1)
我只想知道这样做是否正确
我只想寻求客观的答案,而不是仅仅征求意见。
只要实例属性得到处理,您的代码就会按预期运行:
>>> c = DefaultConfig()
>>> c.a = 'foo'
Traceback (most recent call last):
File "<pyshell#88>", line 1, in <module>
c.a = 'foo'
File "<pyshell#83>", line 10, in __set__
raise ValueError('expecting integer')
ValueError: expecting integer
>>> c.a = 4
>>> c.a
4
在检查DefaultConfig.a
时,__get__
函数仍与instance=None
一起使用。因此,您可以选择以下两种可能的方法之一:
对于后一种方式,代码可能变为:
class IntField:
def __get__(self, instance, owner):
if instance is None:
return getattr(owner, '_default_' + self.name, self)
return instance.__dict__[self.name]
def __set__(self, instance, value):
if not isinstance(value, int):
raise ValueError('expecting integer')
instance.__dict__[self.name] = value
def __set_name__(self, owner, name):
self.name = name
class DefaultConfig:
a = IntField()
_default_a = 2
def __init__(self):
self.a = self._default_a
这里的窍门是按照惯例,属性x
的默认值应为_default_x
。
在这种情况下,您将获得:
print(DefaultConfig.a)
2