如何在类内部自定义并使用装饰器?
问题描述:
想在类内部自定义装饰器log_transaction用来记录用户交易详情,但无法用@staticmethod和@classmethod修饰它,也不能让其作为普通方法,再作为装饰器调用
请问如何正确地在类内部自定义装饰器?
以下代码为何报错?
相关代码:
1.不用@staticmethod和@classmethod
class FundingManagement(object):
def __init__(self, initial_funding):
self.__funding = initial_funding
def log_transaction(self, func):
def inner(*args, **kwargs):
t = Transaction()
t.balance = func(*args, **kwargs)
t.date = datetime.datetime.now().strftime('%Y-%m-%d')
if func.__name__ == 'deposit':
t.kind = '存款'
elif func.__name__ == 'withdrawal':
t.kind = '取款'
elif func.__name__ == 'transfer':
t.kind = '网转'
t.value = args[1]
t.currency = '人民币'
t.print_transaction_details()
return
return inner
@log_transaction
def deposit(self, value):
self.__funding += value
return self.__funding
@log_transaction
def withdrawal(self, value):
self.__funding -= value
return self.__funding
@log_transaction
def transfer(self, value):
self.__funding += value
return self.__funding
相关截图:
相关代码:
2.使用@classmethod
class FundingManagement(object):
def __init__(self, initial_funding):
self.__funding = initial_funding
@classmethod
def log_transaction(cls, func):
def inner(*args, **kwargs):
t = Transaction()
t.balance = func(*args, **kwargs)
t.date = datetime.datetime.now().strftime('%Y-%m-%d')
if func.__name__ == 'deposit':
t.kind = '存款'
elif func.__name__ == 'withdrawal':
t.kind = '取款'
elif func.__name__ == 'transfer':
t.kind = '网转'
t.value = args[1]
t.currency = '人民币'
t.print_transaction_details()
return
return inner
@log_transaction
def deposit(self, value):
self.__funding += value
return self.__funding
@log_transaction
def withdrawal(self, value):
self.__funding -= value
return self.__funding
@log_transaction
def transfer(self, value):
self.__funding += value
return self.__funding
相关截图:
相关代码:
2.使用@staticmethod
class FundingManagement(object):
def __init__(self, initial_funding):
self.__funding = initial_funding
@staticmethod
def log_transaction(func):
def inner(*args, **kwargs):
t = Transaction()
t.balance = func(*args, **kwargs)
t.date = datetime.datetime.now().strftime('%Y-%m-%d')
if func.__name__ == 'deposit':
t.kind = '存款'
elif func.__name__ == 'withdrawal':
t.kind = '取款'
elif func.__name__ == 'transfer':
t.kind = '网转'
t.value = args[1]
t.currency = '人民币'
t.print_transaction_details()
return
return inner
@log_transaction
def deposit(self, value):
self.__funding += value
return self.__funding
@log_transaction
def withdrawal(self, value):
self.__funding -= value
return self.__funding
@log_transaction
def transfer(self, value):
self.__funding += value
return self.__funding
相关截图:
尝试过的解决方式:
在FundingManagerment类外创建了Log类,将log_transaction作为Log类的静态函数
在FundingManagerment类中使用@Log.log_transaction修饰那几个方法
这样虽然行得通,但是我认为这样破坏了封装性,自定义log_transaction的初衷就是只用来修饰FundingManagerment其他几个方法的,并不是一个通用的装饰器
相关代码:
class Log(object):
@staticmethod
def log_transaction(func):
def inner(*args, **kwargs):
t = Transaction()
t.balance = func(*args, **kwargs)
t.date = datetime.datetime.now().strftime('%Y-%m-%d')
if func.__name__ == 'deposit':
t.kind = '存款'
elif func.__name__ == 'withdrawal':
t.kind = '取款'
elif func.__name__ == 'transfer':
t.kind = '网转'
t.value = args[1]
t.currency = '人民币'
t.print_transaction_details()
return
return inner
正在回答
同学,你好!
(1)在相关代码1中,报错的原因是类型错误: log_transaction()缺少1个所需的位置参数:'func',在类内部自定义装饰器无需self参数
(2)在相关代码2中使用@classmethod的情况下,报错原因是类型错误: 'classmethod'对象不可调用,在@classmethod下定义的函数是不能作为装饰器的
(3)在相关代码2中使用@staticmethod的情况下,报错原因是类型错误: 'staticmethod'对象不可调用,在@staticmethod下定义的函数也是不能作为装饰器的
(4)很不错,最后同学尝试过的解决办法很聪明,这个方法的确是破坏了类的封装性,在类内部自定义并使用装饰器可参考(1)
祝学习愉快!
- 参与学习 人
- 提交作业 16233 份
- 解答问题 4470 个
全新版本覆盖5大热门就业方向:Web全栈、爬虫、数据分析、软件测试、人工智能,零基础进击Python全能型工程师,从大厂挑人到我挑大厂,诱人薪资在前方!
了解课程
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星