在 Python 中从 __init__ 调用 setter

Posted

技术标签:

【中文标题】在 Python 中从 __init__ 调用 setter【英文标题】:call a setter from __init__ in Python 【发布时间】:2016-06-23 01:16:45 【问题描述】:

如何从__init__ 内部调用 Python (v2.7) setter 属性?我写了以下课程,但我不知道如何更改它以使其工作。我得到一个AttributeError: 'test' object has no attribute '_x' 异常。这里有一些类似的问题,但到目前为止找不到答案。这个想法是当调用初始化程序进行一些处理/切片并将结果分配给属性时

class test(object):
    def __init__(self, a,b):
        self._x = self.x(a,b)

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

    @x.setter
    def x(self, a, b):
        self._x = "Get this from  and make a dataframe like ".format(a,b)

【问题讨论】:

【参考方案1】:

self.x 是一个属性,因此您只需像使用常规属性一样直接分配给它:

def __init__(self, a, b):
    self.x = (a, b)

然而,setter 总是被赋予 一个 对象;在上述情况下,它被传递一个元组;你可以打开它:

@x.setter
def x(self, value):
    a, b = value
    self._x = "Get this from  and make a dataframe like ".format(a,b)

注意value 参数;这是赋值被传递给 setter 的结果。

演示:

>>> class test(object):
...     def __init__(self, a, b):
...         self.x = (a, b)
...     @property
...     def x(self):
...         return self._x
...     @x.setter
...     def x(self, value):
...         a, b = value
...         self._x = "Get this from  and make a dataframe like ".format(a,b)
...
>>> t = test(42, 'foo')
>>> t.x
'Get this from 42 and make a dataframe like foo'

【讨论】:

啊,我明白了!太好了,现在工作正常,非常感谢。我的 IDE Pycharm 抱怨 instance attribute _x is defined outside __init__,在使用 self._x = None 调用 setter 之前,我已在初始化程序中将其分配给 None。我想没关系,对吧? @Aenaon 如果您将__init__ 函数更改为使用self._x = self.x = (a, b) 行而不是将其实例化为None,它可能看起来更漂亮。 根本不需要初始化为None;它将由__init__ 中的属性设置。 对,但是 PyCharm 抱怨 self._x 是在 @x.setter 而不是 __init__ 中设置的实例变量(我在精神上同意这一点,即使它在案例或属性中被误导)。因此,他在 self.x = (a, b) 之前添加了 self._x = None 行以避免 linter 警告。 @JaredGoguen:当然有更好的方法来消除该警告。

以上是关于在 Python 中从 __init__ 调用 setter的主要内容,如果未能解决你的问题,请参考以下文章

__init__() 应该调用父类的 __init__() 吗?

为啥 Python 在创建实例时不调用实例方法 __init__() 而是调用类提供的 __init__() ?

如何在python中从字典创建属性?

Python没有执行__init__

如何在 Windows 10 中从 bash 提示符运行 python '__main__' 程序文件?

如何在 Python 中调用超级构造函数?