我试图操纵__mro__
但它只读
用例如下:
从pyodbc(DBAPI)创建的Connection对象,用于提供名为“autocommit”的属性。最近我在pyodbc周围包装了一个SQLAlchemy数据库连接池,以便更好地进行资源管理。新的数据库池将返回_ConnectionFairy
,这是一个连接代理类,不再公开autocommit
属性。
我非常希望单独留下第三方代码。因此,_ConnectionFairy
的继承实际上不是一个选项(我可能需要覆盖Pool类来更改它创建连接代理的方式。有关源代码,请参阅here)
一个相当不太优雅的解决方案是改变
的所有出现conn.autocommit = True
到
# original connection object is accessible via .connection
conn.connection.autocommit = True
所以,我想知道是否有可能将一组getter,setter和property注入_ConnectionFairy
的实例
答案 0 :(得分:10)
您可以使用以下语法“扩展”几乎所有类:
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方法,它将在后台执行。这不是你问的,但我希望它会以某种方式帮助你。