Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
重写外部库中的python实例方法_Python_Overriding_Cx Oracle - Fatal编程技术网

重写外部库中的python实例方法

重写外部库中的python实例方法,python,overriding,cx-oracle,Python,Overriding,Cx Oracle,我已经为数据库连接编写了一个上下文管理器。 我希望重写外部类中的方法(cx_oracle.Cursor中的“execute”),在将查询传递到数据库之前删除任何无关的绑定变量(否则会导致DatabaseError)。他们为什么会在那里开始的问题是正交的 下面的方法很管用,但我想知道我在这里是否正确地使用了\u getattribute\u(以前我真的没有理由使用它) 我也“全神贯注”…呃,如果有人对如何克服这个外部库中的方法有更好的建议的话 谢谢。我正在使用python 2.7 import c

我已经为数据库连接编写了一个上下文管理器。 我希望重写外部类中的方法(cx_oracle.Cursor中的“execute”),在将查询传递到数据库之前删除任何无关的绑定变量(否则会导致DatabaseError)。他们为什么会在那里开始的问题是正交的

下面的方法很管用,但我想知道我在这里是否正确地使用了\u getattribute\u(以前我真的没有理由使用它)

我也“全神贯注”…呃,如果有人对如何克服这个外部库中的方法有更好的建议的话

谢谢。我正在使用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())

如果使用
\uuuu getattr\uuuu
方法,而不是
\uuuu getattribute\uuuuu
,则不必在自己的类中对名称进行特殊的大小写。如果无法通过常规方法找到属性,它只会查看
\uuuu getattr\uuuu

比如:

def __getattr__(self, name):
    return getattr(self.curs, name)

您需要将
类游标(cx\u Oracle.Cursor):
更改为
类游标(对象):
。要想通过子类化完成您想要做的事情是很棘手的,因为游标是由数据库连接的方法创建的。您也可以对SessionPool进行子类化,这样它的
cursor
方法将返回您的自定义cursor实例,但这可能不值得您付出努力。

谢谢!这看起来正是我想要的(我需要更加熟悉特殊的方法)。首先,我将cx_Oracle.Cursor子类化的唯一原因是自动获取其其他方法。这给了我这个。@Gerrat:不客气。这里有很多信息: