无法装饰第三方只读功能,如何包装它以获得附加功能?

Can't decorate third party read-only function, how to wrap it for additional functionality?

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

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 调用?

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

充其量你可以写一个包装器class:

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)

然后每次都将光标放在 class 中:

cursor = CursorWrapper(connection.cursor())