无法装饰第三方只读功能,如何包装它以获得附加功能?
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())
我有以下(高度简化的)装饰器:
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())