我试图操纵 __mro__ 但它是只读的
用例如下:
从 pyodbc(一个 DBAPI)创建的连接对象用于提供一个名为“autocommit”的属性。最近我在 pyodbc 周围包装了一个 SQLAlchemy 数据库连接池,以便更好地管理资源。新的数据库池将返回一个 _ConnectionFairy,一个连接代理类,它不再公开 autocommit 属性。
我非常想单独留下第三方代码。所以继承 _ConnectionFairy 并不是一个真正的选择(我可能需要重写 Pool 类来改变它创建连接代理的方式。有关源代码,请参阅 here )
一个不太优雅的解决方案是改变所有出现的
conn.autocommit = True
到
# original connection object is accessible via .connection
conn.connection.autocommit = True
所以,我想知道是否有可能向 _ConnectionFairy 的实例注入(inject)一组 getter、setter 和属性
请您参考如下方法:
您可以使用以下语法“扩展”几乎任何类:
def new_func(self, param):
print param
class a:
pass
a.my_func = new_func
b = a()
b.my_func(10)
更新
如果您想为某些方法创建某种包装器,您可以使用 getattr 和 setattr 来保存原始方法并将其替换为您的实现。我已经在我的项目中完成了,但方式有点不同:
这是一个例子:
class A:
def __init__(self):
setattr(self, 'prepare_orig', getattr(self,'prepare'))
setattr(self, 'prepare', getattr(self,'prepare_wrapper'))
def prepare_wrapper(self,*args,**kwargs):
def prepare_thread(*args,**kwargs):
try:
self.prepare_orig(*args,**kwargs)
except:
print "Unexpected error:", sys.exc_info()[0]
t = threading.Thread(target=prepare_thread, args=args, kwargs=kwargs)
t.start()
def prepare(self):
pass
这段代码的想法是其他开发人员只需在派生类中实现 prepare 方法,它将在后台执行。这不是你问的,但我希望它能以某种方式帮助你。
