无法装饰第三方只读功能,如何包装其他功能?

时间:2019-03-29 16:01:19

标签: python python-3.x wrapper pyodbc python-decorators

我有以下(大大简化的)装饰器:

def log_and_execute(func):
    def wrapper(*args, **kwargs):
        print(*args, **kwargs)
        return func(*args, **kwargs)
    return wrapper

我想用它来装饰pyodbc.connect.cursor

由于我显然无法编辑源代码来执行此操作,因此我尝试这样做:

import pyodbc

connection = pyodbc.connect("connection_string_here")
cursor = connection.cursor()

cursor.execute = log_and_execute(cursor.execute)

但是出现以下错误:

AttributeError: 'pyodbc.Cursor' object attribute 'execute' is read-only

我应该怎么做,这样我就不必更改所有已经存在的cursor.execute通话了?

1 个答案:

答案 0 :(得分:2)

您不能更改pyodbc Cursor类,它是用C语言编写的,并且不允许设置属性。

充其量您可以编写一个包装器类:

class CursorWrapper:
    def __init__(self, cursor):
        self.cursor = cursor

    def execute(self, *args, **kwargs):
        print(*args, **kwargs)
        return self.cursor.execute(*args, **kwargs)

    def __getattr__(self, attr):
        return getattr(self.cursor, attr)

    def __iter__(self):
        return iter(self.cursor)

    def __enter__(self):
        return self.cursor.__enter__()

    def __exit__(self, *args, **kwargs):
        return self.cursor.__exit__(*args, **kwargs)

然后每次将光标包裹在该类中:

cursor = CursorWrapper(connection.cursor())