Python描述符中instance和owner的用途是什么?

2024-05-29 10:31:08 发布

您现在位置:Python中文网/ 问答频道 /正文

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

object.__get__(self, instance, owner)

现在我读到documentation说:

owner is always the owner class, while instance is the instance that the attribute was accessed through, or None when the attribute is accessed through the owner.

不幸的是,我很难理解这意味着什么。所有者是指类本身吗?类对象?那么实例传递给它的目的是什么呢?你知道吗


Tags: the实例方法instanceselfgetobjectis
3条回答

Does owner refer to the class itself?

是的。你知道吗

The class object?

这是完全一样的事情。你知道吗

Then what is the purpose of instance being passed to it?

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

想想这个

 __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的值存储在instance__dict__中,但是如果你不能访问描述符类本身中的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')

这些关系可以用以下代码来说明:

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

相关问题 更多 >

    热门问题