【发布时间】:2019-08-20 14:55:36
【问题描述】:
我有以下(高度简化的)装饰器:
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 调用?
【问题讨论】:
-
你不能。为什么不创建一个仅代理存储为属性的游标的包装器对象?
-
@MartijnPieters 我不确定您的解决方案是什么意思。我正在尝试这样做,这样我就不必更改所有现有的
cursor.execute调用。 -
Cursor中使用的pyodbc类完全用 C 编码,不能进行猴子补丁。您唯一的选择是创建自己的类,该类使用__getattr__和更多__dunder__特殊方法来代理对包装的游标实例的调用(您需要额外的特殊方法来支持迭代和上下文管理器支持pyodbc 游标实现)。__getattr__方法只是从游标实例中获取相同的属性并返回它。这就是您可以应用额外包装的关键,例如打印。 -
@MartijnPieters 你想将你的评论扩展到一个答案,它显示了一个示例类吗?
标签: python python-3.x wrapper pyodbc python-decorators