Descriptor
Table of Contents
__get__(self, instance, owner)
__set__(self, instance, value)
__delete__(self, instance)
 
class Descriptor(object):
 
    def __init__(self):
        self._name = ''
 
    def __get__(self, instance, owner):
        print "Getting: %s" % self._name
        return self._name
 
    def __set__(self, instance, value):
        print "Setting: %s" % value
        self._name = value
 
    def __delete__(self, instance):
        print "Deleting: %s" %self._name
        del self._name
 
class Person(object):
    name = Descriptor()

note:

  • descriptor is class attribute
  • the instance in th api signature of getis the the instance that owns the descriptor variable, in the above case, the instance will be an instance of Person class. id(instance) = id(p), and owner is the class that owns the descriptor, it would be Person. if you call like Person.name, instance will be None.

it is like:

suppose class Person has an instance x, and class Person has name as descriptor, then x.name is like:

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

If we access it like Person.name, then it is like:

Person.__dict__['name'].__get__(None, Person)
print 'name class is :', Person.__dict__['name'].__class__
# out put will be
# name class is : <class '__main__.Descriptor'>

also notice instance p.dict has no attribute 'name'

  • for set, the instance must have value.it can not be None.

one interesting thing here, if we call Person.name = 'abc'
then the whole descriptor will be removed, name becomes regular class attributes. This is determinated by order: class attributes, data descriptor, instance attributes, Non-data descriptors(such as functions), defaulting to getattr()

  • Descriptor.Init will be called only Once no matter how many instances of Person.
  • the above descriptor class stores the value in itself rather than in the instance, as this means you only have one value shared between all instances of Person. if it is not you want, change self.value to instance.value

like:

  def __get__(self, instance, owner):
    return instance.__dict__[self._name]
  def __set__(self, instance, value):
    return instance.__dict__[self._name] = value
  • id of name
x = 'abc'
p = Person()
print 'id name = ', id(p.name)
 
p.name = x
print 'id name = ', id(p.name)

when we call the above code.
for the first print, id(name = id (self._name)

in the second print id(name) will be equal to id(x).

get object value from id

import ctypes
print ctypes.cast(id(p.name), ctypes.py_object).value
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License