Python描述符中实例和所有者的目的是什么?

问题描述 投票:1回答:3

我试图理解Python中的描述符。我似乎无法理解的是描述符方法中的实例和所有者是什么:

object.__get__(self, instance, owner)

现在我读了documentation说:

owner始终是所有者类,而instance是通过所有者访问属性时访问该属性的实例,或者是None。

不幸的是,我无法理解这意味着什么。业主是否参考了班级本身?类对象?然后传递给它的实例的目的是什么?

python python-descriptors
3个回答
0
投票

业主是否参考了班级本身?

是。

类对象?

这是完全相同的事情。

然后传递给它的实例的目的是什么?

描述符如何访问在其他地方查找的实例?例如,如果你使用内置的property类型,它可以通过存储访问器函数并回调这些函数来工作。这些函数期望当前实例作为第一个参数(规范地命名为“self”)。如果描述符没有获得当前实例,则显然无法将其传递给访问者。


0
投票

可以通过以下代码说明关系:

class DescriptorClass:
    def __get__(self, instance, owner):
        return self, instance, owner

class OwnerClass:
    descr = DescriptorClass()

ownerinstance = OwnerClass()

self, instance, owner = ownerinstance.descr

assert self is OwnerClass.__dict__['descr']
assert instance is ownerinstance
assert owner is OwnerClass

self, instance, owner = OwnerClass.descr
assert instance is None

0
投票

考虑一下

 __get__(self, instance, owner):

owner - 这是指创建描述符对象的类,记住描述符对象是在类级别定义的。

instance - 这是指你定义描述符对象的类owner的对象。

instance传递给描述符的__get__方法的目的是确保我们知道并识别您正在访问描述符实例的owner类的哪个对象。

由于描述符对象是在类级别创建的,因此描述符类本身的简单实现可能导致owner类的多个对象覆盖描述符实例的值。以下是此类代码的示例

def __get__(self, instance, owner):
    return self.data

def __set__(self, instance, data):
    if value < 1:
        raise Exception("Negative or zero is not allowed")
    else:
        self.data = value

所以在上面的例子中,data的值只存储在描述符实例中,如果要创建owner类的多个对象,并且假设这些对象设置了data的值,则此代码将产生严重的副作用。

所以为了解决这个问题,你需要将data的值存储在__dict__instance中,但是如果你在描述符类本身没有访问instance的话你会怎么做?因此,根据我的经验,这是在描述符类中使用instance的主要目的。作为解决上述问题并使用instance的参考,这里是代码

class DataDescriptor(object):
    def __init__(self, attribute):
        self.default = 100
        self.attribute = attribute

    def __get__(self, instance, owner):
        print('Getting the value of', self.attribute,
              '__get__ of Data descriptor invoked')
        return instance.__dict__.get(self.attribute, self.default)

    def __set__(self, instance, value=200):
        if value > 0:
            print('__set__ of Data descriptor invoked')
            instance.__dict__[self.attribute] = value
        else:
            sys.exit('Negative value not allowed')
© www.soinside.com 2019 - 2024. All rights reserved.