python - 装饰方法时访问绑定方法或自身
问题描述
我有一个用例,我想用另一种调用方法来装饰方法,例如在此代码中:
def decorator(func):
def enhanced(*args, **kwargs):
func(*args, **kwargs)
func.enhanced = enhanced
return func
@decorator
def function():
pass
class X:
@decorator
def function(self):
pass
x = X()
function()
function.enhanced()
x.function()
# x.function.enhanced()
x.function.enhanced(x)
前三个调用按预期工作,但x.function.enhanced()
没有;我必须写信x.function.enhanced(x)
才能让它发挥作用。我知道这是因为func
传递给装饰器的不是绑定方法而是函数,因此需要self
显式传递。
但我怎样才能解决这个问题?从我对描述符的了解来看,它们仅在查找类时才相关,并且由于func
不是类,func.enhanced
因此无法以我可以拦截的方式查找。
有什么我可以在这里做的吗?
解决方案
您可以返回一个描述符,该描述符返回一个对象,该对象使自身可调用并且具有enhanced
映射到您的enhanced
包装函数的属性:
from functools import partial
def decorator(func):
class EnhancedProperty:
# this allows function.enhanced() to work
def enhanced(self, *args, **kwargs):
print('enhanced', end=' ') # this output is for the demo below only
return func(*args, **kwargs)
# this allows function() to work
def __call__(self, *args, **kwargs):
return func(*args, **kwargs)
def __get__(self, obj, objtype):
class Enhanced:
# this allows x.function() to work
__call__ = partial(func, obj)
# this allows x.function.enhanced() to work
enhanced = partial(self.enhanced, obj)
return Enhanced()
return EnhancedProperty()
以便:
@decorator
def function():
print('function')
class X:
@decorator
def function(self):
print('method of %s' % self.__class__.__name__)
x = X()
function()
function.enhanced()
x.function()
x.function.enhanced()
会输出:
function
enhanced function
method of X
enhanced method of X
推荐阅读
- python - 使用python检查2个数据帧之间的逗号分隔列值中的部分字符串
- python - 找到句子中的第一个数字单词
- powershell - 需要将时间与字符串分开
- php - .htaccess 在匹配包含 URL 中的单词时调用特定页面
- oracle - 生成从两个日期开始的连续期间(对于一对 ID 和值)
- javascript - 如何给出还剩多少次尝试
- google-bigquery - 在 Java 类中读取 BigQuery 表数据(Pojo)
- sql - SQL 查询不确定如何匹配同一表中的不同值
- javascript - 可以在 ES6 类定义中使用箭头函数吗?
- java - Java swing Jframe 不会被 setVisible(false) 隐藏