简体   繁体   English

python中描述符概念的行为(令人困惑)

[英]behaviour of descriptor concept in python (confusing)

I understood python descriptor but I have a little confusion about this.. 我了解python描述符,但对此有些困惑。

if you have a class descriptor as follows 如果您具有以下类描述符

class Descriptor(object):
    def __get__(self, instance, owner):
        print 'getting'
        return self.value
    def __set__(self, instance, value):
        print 'setting'
        self.value = value
    def __delete__(self, instance):
        print 'deleting'
        del self.value

and a class whose attributes we want to manage is something like this.. 我们要管理其属性的类是这样的。

class Test(object):
    name = Descriptor()
    def __init__(self, name):
        print 'init test'
        self.name = name

when I create object of class Test and do something it gives me answer like this... 当我创建Test类的对象并执行某些操作时,它会给我这样的答案...

t = Test('abc')
init test
setting
>>> t.name
getting 
'abc'
>>> del t.name
deleting
>>> t
<__main__.Test object at 0x013FCCD0>
>>> t.name
getting 

Now I want to have a class Test1 something like this.. 现在我想要一个类Test1像这样。

class Test1(object):
    def __init__(self, value):
        print 'init test1'
        self.name = Descriptor()
        self. value = value

and if I create object of Test1 and try to access attribute of instance of Test1, I get output something like this.. 如果我创建Test1的对象并尝试访问Test1实例的属性,则会得到类似以下的输出。

t1 = Test1(12)
t1.name
>>> getting
>>> 12
>>> t1.name = 30
>>> setting

Q 1) my question is that is this name attribute declared in init of Test1, is bound to instance of Test1 or not... because when I try to get attribute dictionary of t1, it return empty dict... Q 1)我的问题是这个名称属性是否在Test1的init中声明,是否绑定到Test1的实例...因为当我尝试获取t1的属性字典时,它返回空dict ...

t1.__dict__
>>> {}

same for class Test's instance t 与类Test的实例t相同

 t.__dict__
 >>> {}

When I add a new attribute to any of these instances, like this... 当我向这些实例中的任何一个实例添加新属性时,就像这样...

 t.some = 'some'
 >>> t1.some = 'some'

and again if I try to access attribute dictionary it gives me only which I have added just now.. now all instance attribute 再一次,如果我尝试访问属性字典,它只会给我刚才添加的内容..现在所有实例属性

t.__dict__
>>> {'some': 'some'}
>>> t1.__dict__
>>> {'some': 'some'}

Q 2) So what is the difference between instance attributes defined in init (like variable name and value in class Descriptor and Test) and attributes defined after instance creation (like variable t.some). 问题2)那么init中定义的实例属性(如类Descriptor和Test中的变量名称和值)与实例创建后定义的属性(如变量t.some)之间有什么区别?

Q 3) How class Test is different than class Test1. 问3)类Test与类Test1有何不同。

In Test1 your Descriptor isn't really used as a descriptor, it's just a normal attribute called name , that happens to have some the special methods. Test1您的Descriptor并没有真正用作描述符,它只是一个名为name的普通属性,碰巧有一些特殊方法。 But that doensn't really make it a descriptor yet. 但这还不是真正的描述符。

If you read the docs about how descriptors are invoked, youll see the mechanism that is used to invoke the descriptors methods. 如果您阅读有关如何调用描述符的文档 ,则会看到用于调用描述符方法的机制。 In your case this would mean t.name woud be roughly equivalent to: 在您的情况下,这意味着t.name将大致等于:

type(t).__dict__['name'].__get__(t, type(t))

and t1.name : t1.name

type(t1).__dict__['name'].__get__(t1, type(t1))

name is looked up in the __dict__ of the class, not of the instance, so that's where the difference is, Test1.__dict__ doesn't have a descriptor called name : name是在类的__dict__中查找的,而不是在实例中Test1.__dict__ ,因此,区别在于Test1.__dict__没有名为name的描述符:

>>> Test.__dict__['name']
<__main__.Descriptor object at 0x7f637a57bc90>
>>> Test1.__dict__['name']
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
KeyError: 'name'

What you also should consider, is that your descriptor sets the value attribute on itself, that means all instances of Test will share the same value: 您还应该考虑的是,描述符自己设置了value属性,这意味着Test所有实例将共享相同的值:

>>> t1 = Test(1)
init test
setting
>>> t2 = Test(2)
init test
setting
>>> t1.name
getting
2
>>> t2.name
getting
2
>>> t1.name = 0
setting
>>> t2.name
getting
0

I think that what yo acutally want to do is to set value on instance instead of self , that would get you the expected behaviour in Test . 我认为您要做的是在instance上设置value而不是在self上设置value ,这将使您在Test获得预期的行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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