Python递归代理
希望这能解释我想要达到的目标Python递归代理,python,object,proxy,Python,Object,Proxy,希望这能解释我想要达到的目标 class A(object): def hello(self): print "hello" a = A() a.b = A() a.b.c = A() a.b.d = [] a.b.d.append(A()) p = Proxy(a) print p.b "b accessed" <__main__.A object at 0xb73f3bec> print p.b.c "b accessed" "c accesse
class A(object):
def hello(self):
print "hello"
a = A()
a.b = A()
a.b.c = A()
a.b.d = []
a.b.d.append(A())
p = Proxy(a)
print p.b
"b accessed"
<__main__.A object at 0xb73f3bec>
print p.b.c
"b accessed"
"c accessed"
<__main__.A object at 0xb73f3dec>
print p.b.d
"b accessed"
"d accessed"
[<__main__.A object at 0xb73f3bcc>]
print p.b.d[0]
"b accessed"
"d accessed"
<__main__.A object at 0xb73e766c>
print p.b.d[0].hello()
"b accessed"
"d accessed"
"hello called"
"hello"
A类(对象):
def你好(self):
打印“你好”
a=a()
a、 b=a()
a、 b.c=a()
a、 b.d=[]
a、 b.d.append(a())
p=代理(a)
印刷品
“b访问”
印刷品
“b访问”
“c访问”
打印p.b.d
“b访问”
“d已访问”
[]
打印p.b.d[0]
“b访问”
“d已访问”
打印p.b.d[0].hello()
“b访问”
“d已访问”
“你好,打电话来”
“你好”
基本上,只要我沿着一个结构走下去,它就会不断返回代理对象。最好只在第一次访问属性并存储在“父对象”上时创建这些代理对象。这样做的目的是,在对(嵌套)对象调用任何方法之前,我可以执行一些逻辑
我看了一下:
但是它只做第一层,我看不出如何操作它来满足我的需要。使用全局缓存,并创建一个代理工厂方法,在创建新代理之前首先检查全局缓存 请注意,此解决方案不在“父”上存储子代理对象。相反,它使用
id(obj)
技巧从缓存中检索对象,不管对象有多深
NOT_FOUND = object()
# global proxy cache
_id2obj_dict = {}
def remember(oid, proxy):
_id2obj_dict[oid] = proxy
return oid
def id2obj(oid):
print("accessing cahed object")
return _id2obj_dict[oid]
class A(object):
def hello(self):
print "hello"
class Proxy(object):
@classmethod
def create(cls, obj):
''' object factory '''
oid = id(obj)
if oid in _id2obj_dict:
return id2obj(oid)
proxy = cls()
proxy.obj = obj
remember(oid, proxy)
return proxy
def __getattr__(self, attr):
prop = getattr(self.obj, attr, NOT_FOUND)
if prop is NOT_FOUND:
raise AttributeError()
print("{} accessed".format(attr))
proxy = Proxy.create(prop)
return proxy
def __getitem__(self, index):
prop = self.obj.__getitem__(index)
proxy = Proxy.create(prop)
return proxy
def __call__(self):
print("{} called".format(self.obj.__name__))
return self.obj()
a = A()
a.b = A()
a.b.c = A()
a.b.d = []
a.b.d.append(A())
p = Proxy.create(a)
<> P>有一些选择要考虑递归代理,有不同的权衡:
@ProxyWhenFlag(“打开代理”)
A类:
def你好(self):
打印“你好”
a=a()
a、 b=a()
a、 b.c=a()
a、 b.d=[]
a、 b.d.append(a())
用法:
>>> a.b
<__main__.A object at 0xb73f3bec>
>>> a.__turn_on_proxy__ = True
>>> a.b
"b accessed"
<__main__.A object at 0xb73f3bec>
>>a.b
>>>a.。\uuuu打开\u代理\uuuuu=True
>>>a.b
“b访问”
\uuu getattribute\uuu
来拦截对象的大多数属性访问
一个简单的方法是为您的代理创建一个imprint
方法,该方法将删除所有其他方法,并且只允许通过代理方法访问底层对象
注意:\uuuuu
基本方法必须单独重写(它们不会被\uuuuu getattribute\uuuu
拦截)<代码>元组、具有插槽的对象
和数据结构(列表
、Dict
、集
等)都进行了优化,\uuuu getattribute\uuuu
也不会在那里工作
更复杂的方法是将对象标记为代理,并通过覆盖对象
,元组
,列表
,Dict
,设置
等来检查标记,从而处理代理。您可以使用bankedenfruit
模块覆盖内置方法。做这件事要特别小心。它非常重要,会影响整个应用程序的性能。不过,如果您要代理几乎所有内容(程序分析/跟踪/AOP框架等),那么它仍然是值得的