python - 为什么 Python 属性需要同名的辅助函数?

标签 python properties overloading

docs解释属性,据说:

Be sure to give the additional functions the same name as the original property (x in this case.)

即,getter、setter 和 deleter 方法必须具有相同的名称。

为什么?而且,Python 禁止方法重载,不是吗?

编辑: 为什么以下代码在 Python 2.6 中运行时会失败?

class Widget(object):
    def __init__(self, thing):
        self.thing = thing
        print self.thing

    @property
    def thing(self):
        return self._thing

    @thing.setter
    def set_thing(self, value):
        self._thing = value


if __name__ == '__main__':
    Widget('Some nonsense here')  

它的输出是:

 Traceback (most recent call last):   
 File "widget.py", line 16, in <module>
     Widget('Some nonsense here')     
 File "widget.py", line 3, in __init__
     self.thing = thing 
 AttributeError: can't set attribute

当 set_thing() 重命名为 thing() 时,代码工作正常。

最佳答案

Python 确实没有方法重载功能,但您是正确的,文档鼓励您以相同的方式命名 getter 和 setter,并演示它以启动。这是怎么回事?

诀窍在于了解方法装饰器在 Python 中的工作原理。每当你看到这样的东西时:

@foo
def bar():
    frob()
    quux()

Python 实际上在幕后做的是这样重写它:

def bar():
    frob()
    quux()
bar = foo(bar)

换句话说:定义一个函数 bar,然后用调用 foo 的结果替换它 bar 函数

虽然这一切都是真的,但就如何解析名称而言,求值顺序实际上与上述略有不同。暂时假装实际发生的事情看起来更接近于此可能更容易:

def __secret_internal_function_name__():
    frob()
    quux()
bar = foo(__secret_internal_function_name__)

为什么这很重要?让我们看看该文档链接中的 Python:

class C(object):
    def __init__(self):
        self._x = None

    @property
    def x(self):
        """I'm the 'x' property."""
        return self._x

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

    @x.deleter
    def x(self):
        del self._x

让我们使用我们现在所知道的来重写它以了解 Python 实际在做什么:

class C(object):
    def __init__(self):
        self._x = None

    def __secret_x_prop__(self):
        """I'm the 'x' property."""
        return self._x
    x = property(__secret_x_prop__)

    def __secret_x_setter__(self, value):
        self._x = value
    x = x.setter(__secret_x_setter__)

    def __secret_x_getter__(self):
        del self._x
    x = x.deleter(__secret_x_getter__)

现在,我们实际上可以看到发生了什么:我们不是在重载函数;而是在重载函数。我们正在逐渐构建一个引用其他函数的 property 对象。

还值得注意的是,根据您创建属性的方式,名称不需要匹配。具体来说,如果您使用 property 函数显式创建属性,就像在文档中的第一个示例中所做的那样,名称可以是您想要的任何名称;该示例将它们称为 getxsetxdelx,并且工作正常。在我假设的安全预防措施中,property.setterproperty.deleterdo 要求传递的函数具有相同的名称,但它们在幕后做的事情与更明确的 property 示例相同。

关于python - 为什么 Python 属性需要同名的辅助函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12730191/

相关文章:

javascript - 无法访问函数内的 Polymer 属性

javascript - 有没有办法从同一对象的方法中创建对象属性?

c++ - 可变模板函数重载失败

python - python中如何调用父类的方法?

python - Pandas:在最大第 n 个定界符之后提取字符串

iphone - 省略属性的 ivars 声明是否会导致麻烦或泄漏?

python - 在其他函数中重新定义python函数

c++ - (C++) 这些重载运算符函数有什么区别?

python - 查找列中的部分文本,如果找到 true 则传递通过反射(reflect)分配的文本值而不是 true 或 false 创建新列

python - 有没有办法提高 opencv 视频处理的速度?