使用python类变量与实例变量



我是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

最新更新