除了原始方法调用之外,我还想修改类方法以执行某些操作。我下面有一个玩具示例。
示例:
class str2(str):
def __init__(self, val):
self.val = val
def upper(self):
print('conveting to upper')
return self.upper()
x = str2('a')
print(x.upper())
这符合我的预期,并给出了最大递归深度错误。是否可以修改upper
方法,使其在调用实际的str.upper
方法之前打印一些文本,而在理想情况下,使名称保持不变?
我一直在想使用装饰器是否是这种情况,但是我对它们还不熟悉,无法清楚地知道如何进行装饰。
答案 0 :(得分:1)
解决方案是:
class str2(str):
def __init__(self, val):
self.val = val
def upper(self):
print('conveting to upper')
return str.upper(self.val)
x = str2('a')
print(x.upper())
在upper
函数中,您只需打印它,然后一次又一次地使用相同的函数
这使得它将继续打印
它最终会引发错误,因为python基本上有足够的
使用方法描述符(<method 'upper' of 'str' objects>
)来使用它,以免它与self
混淆
使用它是因为它仍将调用真实的str
类(而不是元类)
我也自责自己为什么没想到:
class str2(str):
def __init__(self, val):
self.val = val
def upper(self):
print('conveting to upper')
return self.val.upper()
x = str2('a')
print(x.upper())
答案 1 :(得分:1)
在方法str2.upper
中,您要调用str2.upper
,然后依次调用str2.upper
,其中...您会看到它的去向。
您可能打算这样做的是从str.upper
调用str2.upper
。这可以通过使用super
完成。调用super()
返回一个将方法调用委托给父类的对象。
class str2(str):
def upper(self):
print('converting to upper')
return super().upper()
答案 2 :(得分:0)
研究“映射”和“装饰器”-我认为有一种更简单/更Python化的方法来完成您要尝试的操作。
答案 3 :(得分:0)
正如@Schalton所说,有一种方法可以不必使用装饰器从str继承。请考虑以下代码段:
def add_text(func):
def wrapper(*args, **kwargs):
print('converting to upper')
return func(*args)
return wrapper
class str2:
def __init__(self, val):
self.val = val
@add_text
def upper(self):
return self.val.upper()
instance = str2('a')
print(instance.upper())
最大的优点是包装器是可重复使用的,例如如果您要使用完全相同的行为来修改另一个类,则只需添加@decorator即可,而不必重做所有工作。而且,删除其他功能也变得更加容易。