覆盖外部库中的python实例方法

我已经为数据库连接编写了上下文管理器。 我想从外部类(在cx_oracle.Cursor中为\'execute \')覆盖一个方法,以在将查询传递给数据库之前删除所有无关的绑定变量(否则它们将导致DatabaseError)。为什么它们会从那里开始是一个正交的问题。 以下方法可以工作,但是我想知道我在这里是否正确使用_getattribute_(以前并没有真正的借口)。 如果有人对如何从此外部库中重写此方法有更好的建议,我也会“全神贯注”。 谢谢。我正在使用python 2.7
import cx_Oracle
from contextlib import contextmanager

class Cursor(cx_Oracle.Cursor):
    \"\"\"A wrapper for cx_Oracle cursors that will drop extraneous bind variables passed to in\"\"\"

    def __init__(self, curs):
        self.curs = curs

    def execute(self, sql, *args, **kwargs):
        params = {}
        print(\"in execute, args[0] = [%s]\" % str(args[0]))
        if len(args) == 1 and isinstance(args[0], dict):
            for bv in args[0].keys():
                if \':%s\' % bv in sql:
                    params[bv] = args[0][bv]
            print(\'params = %s\' % str(params))
        else:
            return self.curs.execute(sql, *args, **kwargs)

        return self.curs.execute(sql, params)


    def __getattribute__(self, name):
        if name == \'execute\':
            return object.__getattribute__(self, name)
        elif name == \'curs\':
            return object.__getattribute__(self, \'curs\')
        else:
            curs = object.__getattribute__(self, \'curs\')
            return cx_Oracle.Cursor.__getattribute__(curs, name)


@contextmanager
def db_conn():

    pool = cx_Oracle.SessionPool(\"user\", \"pwd\", \"database\", min=2, max=10, increment=1, threaded=True)
    conn = pool.acquire()

    try:
        yield Cursor(conn.cursor())
    except:
        conn.rollback()
        raise
    else:
        conn.commit()
    finally:
        pool.release(conn)


if __name__ == \'__main__\':

    with db_conn() as curs:
        curs.execute(\'select * from dual where 1 = :a\', {\'a\':1, \'b\':2})
        print(curs.fetchall())
    
已邀请:
如果使用a1ѭ方法而不是
__getattribute__
,则不必在您自己的类中使用特殊的名称。如果无法通过常规方法找到该属性,则仅查看
__getattr__
。 就像是:
def __getattr__(self, name):
    return getattr(self.curs, name)
您需要将
class Cursor(cx_Oracle.Cursor):
更改为
class Cursor(object):
。通过子类化来完成您想做的事情很棘手,因为游标是由数据库连接的方法创建的。您也可以对SessionPool进行子类化,以便其
cursor
方法返回您的自定义光标实例,但这可能不值得。     

要回复问题请先登录注册