python 为什么没有重载_关于python:为什么Class property.setter不是方法重载的情况?...

方法重载在Python中是不可能的!您能解释一下为什么Python中的Properties.setter不是方法重载的情况吗?

class newOne():

def __init__(self):

self.__x = 0

@property

def val(self):

return self.__x

@val.setter

def val(self,value):

self.__x = value

在上面的代码中,我有两个名为"val"(但参数集不同)的方法,它们的行为都不同。

你知道属性是描述符吗,这意味着什么?我不想解释这一点,而要理解其余的部分就需要一些知识。但基本上,属性有点神奇,这是一种特殊情况,这里没有实际的方法重载。类只有一个val属性。

class A:def f(): print(1); def f(): print(2); A().f() -> prints 2。第二个定义实际上覆盖了第一个定义。然而,实际中的val.setter将函数定义组成property对象,因此第一个定义实际上并不是"丢失"。然后,描述符开始发挥作用。

这不是方法重载,因为没有两个具有不同签名的方法可以调用。如果是方法重载,可以这样做:

obj = newOne()

print(obj.val())

obj.val(5)

但这不起作用,因为val是一个属性,而不是重载方法。

那那里发生了什么?为什么我们要用相同的名称定义两个方法,如果不重载它们会发生什么?

魔法发生在装饰工身上。作为前提条件,你必须知道

@deco

def func(...):

...

等于

def func(...):

...

func = deco(func)

因此,首先发生的事情是@property修饰器将getter函数转换为一个属性,该函数作为getter函数:

class newOne:

@property

def val(self):

return self.__x

print(newOne.val)

print(newOne.val.fget)

# output:

#

#

在此之后,@val.setter装饰器使用getter和setter函数创建一个新属性:

class newOne:

@property

def val(self):

return self.__x

@val.setter

def val(self, value):

self.__x = value

print(newOne.val)

print(newOne.val.fget)

print(newOne.val.fset)

# output:

#

#

#

(getter和setter函数具有相同的名称,因为它们都被定义为def val(...),但它们仍然是不同的函数。所以他们有不同的身份证。)

所以最后,您有一个带有getter和setter函数的val属性。您没有重载方法。

有关属性如何工作以及如何调用getter和setter函数的详细信息,请参阅描述符文档。

首先,@property修饰器创建一个名为val的描述符,并将其放在一边,以便在定义类后将其添加到类中。然后,@val.setter修饰了它的函数,并简单地将它的引用添加到val描述符中。

您的代码大致相当于

d = {}

def __init__(self):

self.__x = 0

d['__init__'] = __init__

def val(self):

return self.__x

d['val'] = property(val)

def val(self, value):

self.__x = value

# Not d['val'].__set__ = val, as previously stated

d['val'] = property(fget=d['val'], fset=val)

newOne = type('newOne', (object,), d)

# These are all"local" to, or part of the implementation of,

# the class statement, so they don't stick around in the current

# namespace.

del __init__, val, d  # These are all"local" to or part of the imple

–1该名称并不无关紧要。

对@val.setter的调用等同于d['val'] = property(fget=d['val'], fset=val)而不是d['val'].__set__ = val。这可能有助于解释。在这里,你可以使getter和setter的名称不同,这可能使它更清楚。但是wim比ops类定义中的getter和setter必须具有相同的名称,这样最终只有一个属性包含这两个属性。

是的,我想在我回答完之后再检查一遍。看起来应该无关紧要。)

@alexhall是@val.setter真的重新定义了属性,还是这只是在这个伪python中最接近的属性?

它实际上创建了一个新的属性。有点像type(self)(...)。我真的不明白为什么它需要这样做,而不是改变现有的财产,但这就是它要做的。耸肩

实际上我只是在猜测,现在我想你可能是对的。当然,它必须归还一些东西,这样一来,val最终就不是没有了。但它可能只是添加了属性,然后再次返回相同的属性。

如果你知道为什么每次都会创建一个新的属性,那就在这里获得+450点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值