[英]Why is Class property.setter not a case of method overloading?
Method overloading is not possible in Python! 方法重载在Python中是不可能的! Can you please explain why
Properties.setter
in Python is not a case of method overloading? 您能否解释一下为什么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
In the above code, I have two methods with the same name 'val' (but different set of args) and both behave differently. 在上面的代码中,我有两个具有相同名称“ val”(但参数集不同)的方法,并且它们的行为都不同。
First, the @property
decorator creates a descriptor named val
and sets it aside to add to the class once it is defined. 首先,
@property
装饰器创建一个名为val
的描述符,并将其放在一旁,以在定义后添加到类中。 Then, the @val.setter
decorated takes its function and
simply
effectively adds a reference to it to the val
descriptor. 随后,
@val.setter
装饰需要它的功能和
简单
有效地增加了一个引用来的val
描述。
Your code is roughly equivalent to 您的代码大致相当于
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
It's not method overloading because there aren't two methods with different signatures that can be called. 这不是方法重载,因为没有两个具有不同签名的方法可以调用。 If it was method overloading, you could do something like this:
如果是方法重载,则可以执行以下操作:
obj = newOne()
print(obj.val())
obj.val(5)
But that doesn't work, because val
is a property and not an overloaded method. 但这是行不通的,因为
val
是属性而不是重载方法。
So what's going on there? 那到底是怎么回事? Why are we defining two methods with the same name, and what happens to them, if not overloading?
为什么我们要定义两个具有相同名称的方法,如果不重载,它们会发生什么?
The magic happens in the decorators. 魔术发生在装饰器中。 As a prerequisite, you have to know that
作为前提条件,您必须知道
@deco
def func(...):
...
is equivalent to 相当于
def func(...):
...
func = deco(func)
So, the first thing that happens is that the @property
decorator turns your getter function into a property with that function as its getter function: 因此,发生的第一件事是
@property
装饰器将您的getter函数变成一个以该函数作为其getter函数的属性:
class newOne:
@property
def val(self):
return self.__x
print(newOne.val)
print(newOne.val.fget)
# output:
# <property object at 0x002B1F00>
# <function newOne.val at 0x0052EAE0>
After this, the @val.setter
decorator creates a new property with a getter and setter function: 之后,
@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:
# <property object at 0x0221B7B0>
# <function newOne.val at 0x0226EB70>
# <function newOne.val at 0x0226EAE0>
(The getter and setter functions have the same name because they were both defined as def val(...)
, but they're still different functions. That's why they have different ids.) (getter和setter函数具有相同的名称,因为它们都定义为
def val(...)
,但是它们仍然是不同的函数。这就是为什么它们具有不同的id的原因。)
So in the end you have a val
property with a getter and a setter function. 因此,最后您有了一个带有getter和setter函数的
val
属性。 You do not have an overloaded method. 您没有重载的方法。
For details about how properties work and how the getter and setter functions are called, see the descriptor documentation . 有关属性如何工作以及如何调用getter和setter函数的详细信息 ,请参见描述符文档 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.