Why does declaring a descriptor class in the __init__ function break the descriptor functionality?

╄→гoц情女王★ 提交于 2019-12-05 04:57:34

Accordingly to the documentation:

The following methods only apply when an instance of the class containing the method (a so-called descriptor class) appears in the class dictionary of another new-style class, known as the owner class. In the examples below, “the attribute” refers to the attribute whose name is the key of the property in the owner class’ __dict__. Descriptors can only be implemented as new-style classes themselves.

So you can't have descriptors on instances.

However, since the descriptor gets a ref to the instance being used to access it, just use that as a key to storing state and you can have different behavior depending on the instance.

Here's a class that can pass the original tests, but don't try using it in most situations. it fails the isinstance test on itself!

class E(object):
    def __new__(cls, state):
        class E(object):
            a = A(state)
            def __init__(self, state):
                self.state = state
        return E(state)

#>>> isinstance(E(1), E)
#False
Gregory Kuhn

I was bitten by a similar issue in that I wanted to class objects with attributes governed by a descriptor. When I did this, I noticed that the attributes were being overwritten in all of the objects such that they weren't individual.

I raised a SO question and the resultant answer is here: class attribute changing value for no reason

A good document link discussing descriptors is here: http://martyalchin.com/2007/nov/24/python-descriptors-part-2-of-2/

An example descriptor from the aforementioned link is below:

class Numberise(object):
    def __init__(self, name):
        self.name = name

    def __get__(self, instance, owner):
        if self.name not in instance.__dict__:
            raise (AttributeError, self.name)
        return '%o'%(instance.__dict__[self.name])

    def __set__(self, instance, value):
        print ('setting value to: %d'%value)
        instance.__dict__[self.name] = value
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!