Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create per-instance property descriptor?

Usually Python descriptor are defined as class attributes. But in my case, I want every object instance to have different set descriptors that depends on the input. For example:

class MyClass(object):
  def __init__(self, **kwargs):
    for attr, val in kwargs.items():
      self.__dict__[attr] = MyDescriptor(val)

Each object are have different set of attributes that are decided at instantiation time. Since these are one-off objects, it is not convenient to first subclass them.

tv = MyClass(type="tv", size="30")
smartphone = MyClass(type="phone", os="android")

tv.size   # do something smart with the descriptor

Assign Descriptor to the object does not seem to work. If I try to access the attribute, I got something like

<property at 0x4067cf0>

Do you know why is this not working? Is there any work around?

like image 274
Wai Yip Tung Avatar asked May 03 '12 17:05

Wai Yip Tung


1 Answers

This is not working because you have to assign the descriptor to the class of the object.

class Descriptor:

    def __get__(...):
        # this is called when the value is got

    def __set__(...
    def __del__(...

if you write

obj.attr
=> type(obj).__getattribute__(obj, 'attr') is called
=> obj.__dict__['attr'] is returned if there else:
=> type(obj).__dict__['attr'] is looked up
if this contains a descriptor object then this is used.

so it does not work because the type dictionairy is looked up for descriptors and not the object dictionairy.

there are possible work arounds:

  1. put the descriptor into the class and make it use e.g. obj.xxxattr to store the value. If there is only one descriptor behaviour this works.

  2. overwrite setattr and getattr and delattr to respond to discriptors.

  3. put a discriptor into the class that responds to descriptors stored in the object dictionairy.

like image 77
User Avatar answered Sep 22 '22 11:09

User