简体   繁体   English

为什么Class property.setter不是方法重载的情况?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM