我是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
我只想知道是否是正确的方法
我会尽可能客观地回答,而不是只征求意见。
只要实例属性得到处理,代码就会按预期运行:
>>> 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
一起使用。所以你可以从两种可能的方式中选择一种:
- 是透明并显示属性的实际内容(您当前所做的(
- 坚持使用描述符魔术并返回默认值(此处为2(
对于后一种方式,代码可能会变成:
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