如何检查属性是否具有__init__中定义的默认值

时间:2015-12-21 23:16:41

标签: python

如何检查用户是否设置了对象的属性?目前,我有一个班级

class foo:
    def __init__(self):
        self.bar = 'baz'

稍后我想检查用户是否设置了bar的值,例如

my_foo = foo()
my_foo.bar = 'mybaz'

所以我想知道上面的第二行是否已被调用(如果没有则抛出警告)。我有两个解决方案,但我不喜欢其中任何一个:

  1. 检查my_foo.bar是否等于默认值。但可能是用户将my_foo.bar设置为相同的值,然后我不想发出警告。

  2. 不要在__init__中设置默认值,但仅限于使用时。然后,可以使用getattr()进行检查,并使用setattr()进行设置。

  3. 我确信有一种优雅的pythonic方式可以做到这一点,我没有想到。

2 个答案:

答案 0 :(得分:6)

使用@property装饰器构建getter和setter,并让setter在用户更改属性时告诉您,例如

class Foo:

    def __init__(self):
        self._x_was_modified = False
        self._x = None

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, value):
        self._x_was_modified = True
        self._x = value

foo = Foo()
print('x was modified by user: {}'.format(foo._x_was_modified))
foo.x = 42
print('x was modified by user: {}'.format(foo._x_was_modified))

这将输出:

x was modified by user: False
x was modified by user: True

答案 1 :(得分:2)

另一个涉及使用flag的解决方案是通过使用__setattr__方法来完成的:

class foo:
    def __init__(self):
        self._altered = -1
        self.bar = 'baz'

    def __setattr__(self, attrname, val):
        if attrname is 'bar':
            self._altered += 1
        super.__setattr__(self, attrname, val)
        # if you heard super is evil and you feel 
        # funny using it in your code instead use:
        # object.__setattr__(self, attrname, val)

如果有人重新设置此变量,self._altered的值将为正数,因此评估为True(请记住,首先访问{{1}在初始化期间和__init__一次递增。)

在此之后,您可以对表单进行直观的检查:

_altered

完成。只是另一种方式做几乎完全相同的事情。