inspired by Steven Bethard's recipe at http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/442418 this class allows you to use an inner class as an extention of your class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | class Property(object):
_obj = []
class __metaclass__(type):
def __get__(cls, obj, objtype=None):
if obj is not None:
cls._obj.append( obj )
return cls
@staticmethod
def parent_instancemethod(func):
"""
decorator makes the decorated Property method behave like
the Property's parent's instance method
"""
@classmethod
def _parent_instancemethod(cls, *args, **kwds):
return func(cls._obj.pop(), *args, **kwds)
return _parent_instancemethod
@staticmethod
def parent_classmethod(func):
"""
decorator makes the decorated Property method behave like
the Property's parent's class method
"""
@classmethod
def _parent_classmethod(cls, *args, **kwds):
return func(cls._obj.pop().__class__, *args, **kwds)
return _parent_classmethod
# Testing
if __name__ == "__main__":
class A:
a = 10
def method1(self, *args, **kwds):
print "-------------------------"
print "In A.method1()"
print " Object: ", self
print " Arguements: ", args, kwds
print "-------------------------"
@classmethod
def method2(cls, *args, **kwds):
print "-------------------------"
print "In A.method2()"
print " Class: ", cls
print " Arguements: ", args, kwds
print "-------------------------"
@staticmethod
def method3(*args, **kwds):
print "-------------------------"
print "In A.method3()"
print " Arguements: ", args, kwds
print "-------------------------"
class B(Property):
a = 99
b = 'spam'
@Property.parent_instancemethod
def method1(self, *args, **kwds):
print "-------------------------"
print "In A.B.method1()", args, kwds
print " Object: ", self
print " Arguements: ", args, kwds
print "-------------------------"
@Property.parent_classmethod
def method2(cls, *args, **kwds):
print "-------------------------"
print "In A.B.method2()"
print " Class: ", cls
print " Arguements: ", args, kwds
print "-------------------------"
@classmethod
def method3(cls, *args, **kwds):
print "-------------------------"
print "In A.B.method3()"
print " Class: ", cls
print " Arguements: ", args, kwds
print "-------------------------"
@staticmethod
def method4(*args, **kwds):
print "-------------------------"
print "In A.B.method4()"
print " Arguements: ", args, kwds
print "-------------------------"
x = A()
print "x: ", x
print "x.a: ", x.a
print "x.B: ", x.B
x.method1(1, 2, 3)
x.method2(4, 5, 6)
x.method2(7, 8, 9)
print
print "x.B.a: ", x.B.a
print "x.B.b: ", x.B.b
x.B.method1('A', 'B', 'C')
x.B.method2('D', 'E', 'F')
x.B.method3('G', 'H', 'I')
x.B.method4('J', 'K', 'L')
|
I found myself with a class and I wanted to be able to access a nested class like:
myclass.nestedclass.method(x)
Easy enough to do. But further, I wanted nestedclass.method to receive the myclass instance as it's first arguement, as any instance method of myclass would, so I could design nestedclass's methods as though they belonged to myclass. Not having a lot of experience with this sort of thing, I surfed around for answers and found Steven Bethard's recipe for using inner classes as properties. Tooling around with it, I came up with this. I'd appriciate comments, good or bad. Is there a better, easier way acheive the same thing? Is my implimentation of the idea fatally flawed?
Why? It's a neat trick but you haven't said anything about what the motivation is. If the nested class' methods receive the outer class instance as first argument, what purpose does the nested class serve? Why not just define its methods directly on the outer class?