我试图操纵__mro__,但它是只读的

用例如下:

从pyodbc(一种DBAPI)创建的Connection对象,用于提供一个名为“ autocommit”的属性。最近,我将SQLAlchemy db连接池包装在了pyodbc周围,以实现更好的资源管理。新的数据库池将返回_ConnectionFairy,即连接代理类,该类不再公开autocommit属性。

我非常想保留第三方代码。因此,_ConnectionFairy的继承实际上不是一个选择(我可能需要重写Pool类以更改其创建连接代理的方式。有关源代码,请参见here

一个不太好用的优雅解决方案是更改所有

conn.autocommit = True




# original connection object is accessible via .connection
conn.connection.autocommit = True


因此,我想知道是否有可能将一组getter,setter和property注入到_ConnectionFairy的实例中

最佳答案

您可以使用以下语法“扩展”几乎所有类:

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方法,并将在后台执行。这不是您的要求,但我希望它会以某种方式为您提供帮助。

关于python - Python:将新函数注入(inject)类的实例吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4719083/

10-12 02:08