162 lines
4.9 KiB
Python
162 lines
4.9 KiB
Python
import collections
|
|
|
|
__doc__ = """Einfache Objekt Aquisition für Python."""
|
|
|
|
class Aquisition:
|
|
"""Markiert ein Objekt als Ziel von Aquisition durch AquisitionProxy"""
|
|
pass
|
|
|
|
|
|
def caller(inst,a):
|
|
return lambda *args,**kwargs: a.__func__(inst,*args,**kwargs)
|
|
|
|
def call(self,method,*args,**kwargs):
|
|
m = getattr(object.__getattribute__( self, "_o"), method)
|
|
if hasattr(m,"__func__"):
|
|
return m.__func__(self,*args,**kwargs)
|
|
else:
|
|
return m(*args,**kwargs)
|
|
|
|
def getter(attrib):
|
|
return lambda self, *args, **kwargs: call(self,attrib,*args, **kwargs)
|
|
|
|
if hasattr(m, "__func__"):
|
|
return lambda self, *args, **kwargs: m.__func__(self, *args, **kwargs)
|
|
else:
|
|
return lambda self, *args, **kwargs: m(*args, **kwargs)
|
|
|
|
|
|
class AquisitionProxy:
|
|
"""Basisobjekt für Aquisition."""
|
|
_special_names=[
|
|
'__abs__', '__add__', '__and__', '__call__', '__cmp__', '__coerce__',
|
|
'__contains__', '__delitem__', '__delslice__', '__div__', '__divmod__',
|
|
'__eq__', '__float__', '__floordiv__', '__ge__', '__getitem__',
|
|
'__getslice__', '__gt__', '__hash__', '__hex__', '__iadd__', '__iand__',
|
|
'__idiv__', '__idivmod__', '__ifloordiv__', '__ilshift__', '__imod__',
|
|
'__imul__', '__int__', '__invert__', '__ior__', '__ipow__', '__irshift__',
|
|
'__isub__', '__iter__', '__itruediv__', '__ixor__', '__le__', '__len__',
|
|
'__long__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__',
|
|
'__neg__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__',
|
|
'__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__',
|
|
'__repr__', '__reversed__', '__rfloorfiv__', '__rlshift__', '__rmod__',
|
|
'__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__',
|
|
'__rtruediv__', '__rxor__', '__setitem__', '__setslice__', '__sub__',
|
|
'__truediv__', '__xor__', 'next',
|
|
]
|
|
|
|
def _get_proxy_cls(cls,obj):
|
|
ocls = obj.__class__
|
|
ns = {}
|
|
_methods = {}
|
|
|
|
for n in AquisitionProxy._special_names:
|
|
if (hasattr(ocls, n)):
|
|
ns[n] = getter(n)
|
|
|
|
return type( "AProxy(%s)" % (ocls.__name__,), (cls,), ns )
|
|
|
|
|
|
def __new__(cls,obj,p = None,aq_name=None,aq_root=None):
|
|
pcls = AquisitionProxy._get_proxy_cls(cls,obj)
|
|
|
|
inst = object.__new__( pcls )
|
|
|
|
_methods = {}
|
|
for n in dir(obj):
|
|
# print("AQ_ATTR: %s" % (n,))
|
|
a = getattr(obj,n)
|
|
if isinstance( a, collections.Callable ) and hasattr( a, "__func__" ): # and not hasattr( AquisitionProxy, n ):
|
|
# print("AQ_METHOD: %s = %s" % (n,a))
|
|
_methods[n] = caller(inst,a)
|
|
|
|
object.__setattr__( inst, "_methods", _methods )
|
|
object.__setattr__( inst, "_o", obj)
|
|
object.__setattr__( inst, "_p", p)
|
|
object.__setattr__( inst, "_aq_name", aq_name)
|
|
|
|
if (aq_root is None):
|
|
aq_root = inst
|
|
|
|
object.__setattr__( inst, "_aq_root", aq_root)
|
|
|
|
return inst
|
|
|
|
def __getattribute__(self,name):
|
|
v = None
|
|
# print("AQN: %s" % (name,))
|
|
|
|
if name.startswith("_aq_"):
|
|
if (name == "_aq_parent"):
|
|
return object.__getattribute__( self, "_p")
|
|
# return AquisitionProxy( p, self, aq_name=p._aq_name, aq_root=self._aq_root )
|
|
if (name == "_aq_name"):
|
|
n = object.__getattribute__( self, "_aq_name")
|
|
if n is None:
|
|
return "/"
|
|
return n
|
|
if (name == "_aq_object"):
|
|
return object.__getattribute__( self, "_o")
|
|
|
|
return object.__getattribute__( self, name )
|
|
|
|
_methods = object.__getattribute__(self,"_methods")
|
|
if name in _methods:
|
|
return _methods[name]
|
|
|
|
try:
|
|
v = getattr( object.__getattribute__( self, "_o"), name )
|
|
except AttributeError as ae:
|
|
try:
|
|
print("AQN_PARENT: %s %s" % (object.__getattribute__( self, "_p"), name))
|
|
v = getattr( object.__getattribute__( self, "_p"), name)
|
|
if (isinstance(v, AquisitionProxy)):
|
|
v = object.__getattribute__( v, "_o" )
|
|
except AttributeError as ae2:
|
|
raise ae2
|
|
|
|
if isinstance( v, Aquisition ):
|
|
v = AquisitionProxy( v, self, aq_name=name, aq_root=self._aq_root )
|
|
|
|
return v
|
|
|
|
def __setattr__(self,name,value):
|
|
setattr( object.__getattribute__( self, "_o"), name, value )
|
|
|
|
def __delattr__(self,name):
|
|
delattr( object.__getattribute__( self, "_o"), name )
|
|
|
|
def __nonzero__(self):
|
|
return bool(object.__getattribute__(self, "_o"))
|
|
def __str__(self):
|
|
return str(object.__getattribute__(self, "_o"))
|
|
def __repr__(self):
|
|
return repr(object.__getattribute__(self, "_o"))
|
|
|
|
def __dir__(self):
|
|
return dir( object.__getattribute__(self, "_o") )
|
|
|
|
def dir(self,cls):
|
|
realcls = object.__getattribute__( self, "__class__" )
|
|
|
|
ls = []
|
|
|
|
for an in dir(self):
|
|
if issubclass( getattr( self, an ).__class__, cls):
|
|
ls.append(an)
|
|
|
|
if issubclass(realcls,AquisitionProxy):
|
|
p = object.__getattribute__( self, "_p")
|
|
if not p is None:
|
|
for an in AquisitionProxy.dir(p, cls):
|
|
if not an in ls:
|
|
ls.append( an )
|
|
|
|
return ls
|
|
|
|
def _aq_path(self):
|
|
if (self._aq_name is None) or (self._aq_parent is None):
|
|
return ""
|
|
return "%s/%s" % (self._aq_parent._aq_path(),self._aq_name)
|
|
|