【发布时间】:2012-12-08 16:00:28
【问题描述】:
我有以下代码,其中大部分代码看起来很笨拙、令人困惑和/或间接,但其中大部分是为了演示我遇到问题的更大代码的部分。请仔细阅读
# The following part is just to demonstrate the behavior AND CANNOT BE CHANGED UNDER NO CIRCUMSTANCES
# Just define something so you can access something like derived.obj.foo(x)
class Basic(object):
def foo(self, x=10):
return x*x
class Derived(object):
def info(self, x):
return "Info of Derived: "+str(x)
def set(self, obj):
self.obj = obj
# The following piece of code might be changed, but I would rather not
class DeviceProxy(object):
def __init__(self):
# just to set up something that somewhat behaves as the real code in question
self.proxy = Derived()
self.proxy.set(Basic())
# crucial part: I want any attributes forwarded to the proxy object here, without knowing beforehand what the names will be
def __getattr__(self, attr):
return getattr(self.proxy, attr)
# ======================================
# This code is the only I want to change to get things work
# Original __getattr__ function
original = DeviceProxy.__getattr__
# wrapper for the __getattr__ function to log/print out any attribute/parameter/argument/...
def mygetattr(device, key):
attr = original(device, key)
if callable(attr):
def wrapper(*args, **kw):
print('%r called with %r and %r' % (attr, args, kw))
return attr(*args, **kw)
return wrapper
else:
print "not callable: ", attr
return attr
DeviceProxy.__getattr__ = mygetattr
# make an instance of the DeviceProxy class and call the double-dotted function
dev = DeviceProxy()
print dev.info(1)
print dev.obj.foo(3)
我想要的是捕获对DeviceProxy 的所有方法调用,以便能够打印所有参数/参数等等。在给定的示例中,这在调用info(1) 时效果很好,所有信息都会被打印出来。
但是当我调用双点函数dev.obj.foo(3) 时,我只得到消息,这不是可调用的。
如何修改上述代码,以便在第二种情况下也能获得我的信息?只能修改===下面的代码。
【问题讨论】:
-
问题是
dev.obj.foo(3),mygetattr被设备dev和键obj调用,这确实是不可调用的。您需要找到一种使用设备obj和密钥foo调用它的方法。 (如何做到这一点对我来说并不明显。) -
是的,这正是问题所在。看来我需要另一层包装或类似的东西,但我不确定有多少。可能会有像
device.service.info.version.firmware这样的电话。 -
据我所知,“Basic”和“Derived”并没有使用继承,尽管有名称。
标签: python arguments callable getattr