使用python类变量与实例变量

时间:2018-11-08 13:40:00

标签: python python-3.x

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

1 个答案:

答案 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一起使用。因此,您可以选择以下两种可能的方法之一:

  • 透明的,并显示该属性实际上是什么(当前操作)
  • 坚持使用描述符魔术并返回默认值(此处为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