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 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
""" Proxy prototype written in Python. The C version is a little different,
but this should give a general idea of how the type works.
Copyright (c) 2000, Marc-Andre Lemburg; mailto:mal@lemburg.com
Copyright (c) 2000-2011, eGenix.com Software GmbH; mailto:info@egenix.com
See the documentation for further information on copyrights,
or contact the author. All Rights Reserved.
"""
import types
class Proxy:
def __init__(self,object,interface=None):
# All these private attributes will be hidden in the C
# implementation
self.__object = object
if interface:
d = {}
for item in interface:
if type(item) == types.StringType:
d[item] = 1
else:
d[item.__name__] = 1
self.__interface = d
else:
self.__interface = None
if hasattr(object,'__public_getattr__'):
self.__public_getattr = object.__public_getattr__
else:
self.__public_getattr = None
if hasattr(object,'__public_setattr__'):
self.__public_setattr = object.__public_setattr__
else:
self.__public_setattr = None
if hasattr(object,'__cleanup__'):
self.__cleanup = object.__cleanup__
else:
self.__cleanup = None
def __getattr__(self,what):
if self.__interface and not self.__interface.has_key(what):
raise AttributeError,'attribute access restricted'
if self.__public_getattr:
return self.__public_getattr(what)
else:
return getattr(self.__object,what)
def __setattr__(self,attr,obj):
if attr[:8] == '_Proxy__':
self.__dict__[attr] = obj
return
if self.__interface and not self.__interface.has_key(attr):
raise AttributeError,'attribute access restricted'
if self.__public_setattr:
self.__public_setattr(attr,obj)
else:
return setattr(self.__object,attr,obj)
def __del__(self):
if self.__cleanup:
self.__cleanup()
class ProxyFactory:
def __init__(self,Class,interface=()):
self.Class = Class
self.interface = interface
def __call__(self,*args,**kw):
""" Return a new object
"""
return Proxy(apply(self.Class,args,kw),self.interface)
def __repr__(self):
return '<ProxyFactory for %s>' % repr(self.Class)
class A:
a = 1
b = 2
def __init__(self):
self.c = 3
def __public_getattr__(self,what):
""" If given, this method is called for all public getattr access
to the object.
"""
print 'public getattr',what
return getattr(self,what)
def __public_setattr__(self,what,to):
""" If given, this method is called for all public setattr access
to the object.
"""
print 'public setattr',what,'to',to
return setattr(self,what,to)
def write(self,value):
self.a = value
def read(self):
return self.a
def __str__(self):
return str(self.a)
def __cleanup__(self):
""" If given, this method is called if the proxy object gets
garbage collected. You can use it to break circular references
the object might have introduced.
"""
print 'cleanup'
self.__dict__.clear()
AA = ProxyFactory(A,(A.read,A.write,'__str__'))
o = Proxy(A(),(A.read,A.write,'__str__'))
p = AA()
|