Skip to content

Instantly share code, notes, and snippets.

@mtth
Created January 26, 2014 19:04
Show Gist options
  • Save mtth/8637593 to your computer and use it in GitHub Desktop.
Save mtth/8637593 to your computer and use it in GitHub Desktop.
Python descriptors.
class Desc(object):
def __get__(self, obj, type=None):
return 'd'
def __set__(self, obj, value):
pass
class A(object):
pass
a = A()
A.d1 = Desc()
a.d2 = Desc()
# object.__getattribute__ prioritizes instance variables over descriptors
assert(a.d1 == 'd')
assert(type(a.d2) == Desc)
# but type.__getattribute__ doesn't
assert(A.d1 == 'd')
assert(type(A.__dict__['d1']) == Desc)
# functions are (non-data) descriptors, this is where the method transformation comes from
class C(object):
pass
def bar(*args):
return len(args)
C.baz = bar
baz = C.baz
assert(baz != bar)
c = C()
c.bax = bar
bax = c.bax
assert(bax == bar)
# similarly
A.bax = bar
a.baz = bar
assert(a.bar() == 1)
assert(a.baz() == 0)
# descriptors added later override instance variables
class B(object):
d = 0
b = B()
assert(b.d == 0)
b.d = 1
assert(b.d == 1)
B.d = Desc()
assert(b.d == 'd')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment