Python类装饰器的相关问题
本帖最后由 ink_Ocelot 于 2021-6-27 20:48 编辑最近正在做一个用装饰器来检测脚本执行情况并输出项目的模块
我想要装饰的函数是在类中的,也就是方法
假设我的装饰器类在deco,另一个类A中被装饰的方法func
但是当装饰类中的函数时,需要传入实例self
如果用__call__,只能获取到*args和*kwargs,也就是写在括号里的参数
那么就会报错,提示缺少参数
所以我转而使用__get__方法
但是__get__方法只能获取实例和类,不能获取参数
然后我将类A中的所有需要参数的方法改为不需要参数的方法
但是不管我怎么试,他总会在进入第三个方法后提示'NoneType' object is not callable
也就是None不能作为方法使用
这种错误大概出现于:None(),这种使用方法
而装饰器大概讲就是将A.func()变成了deco(A.func())
所以我想是在装饰后传回了一个None,导致了出错
但是我将__get__里调用函数的方法前加了return传回func()后依旧出错
备注:将装饰器注释掉后程序运行正常
装饰器代码如下:
class EPro:
def __init__(self,func):
self.__func = func
def __get__(self, instance, owner):
'''
instance:实例
owner:类
'''
#self.__instance = instance
#print(self.__func)
#print(self.__instance)
try:
logger.info("现在正在进入类[{0}]中方法[{1}].".format(owner.__name__, self.__func.__name__))
return self.__func(instance)
print("退出方法:{}.".format(self.__func.__name__))
except Exception as e:
logger.error("*** 错误通告 ***\n发生时间:{0}\n具体时间戳:{1}\n错误描述:{2}\n类:{3}\n方法:{4}\n详细信息:".format(
time.ctime(), time.time(), e.args, owner.__name__, self.__func.__name__), exc_info = True)
附输出日志:
------------------------------
2021-06-27 20:25:28,270 - Logger - INFO
*** 程序开始运行 时间:Sun Jun 27 20:25:28 2021 ***
------------------------------
2021-06-27 20:25:28,283 - Logger - INFO
现在正在进入类中方法.
------------------------------
2021-06-27 20:25:40,181 - Logger - INFO
现在正在进入类中方法.
------------------------------
2021-06-27 20:25:40,232 - Logger - INFO
现在正在进入类中方法.
------------------------------
2021-06-27 20:25:40,391 - Logger - ERROR
*** 错误通告 ***
发生时间:Sun Jun 27 20:25:40 2021
具体时间戳:1624796740.391237
错误描述:'NoneType' object is not callable
类:main
方法:mainLoop
详细信息:
Traceback (most recent call last):
File "K:\xxx\main.py", line 115, in __get__
return self.__func(instance)
File "K:\xxx\main.py", line 176, in mainLoop
self.fpsCheck()
TypeError: 'NoneType' object is not callable
------------------------------
2021-06-27 20:25:40,420 - Logger - ERROR
*** 错误通告 ***
发生时间:Sun Jun 27 20:25:40 2021
具体时间戳:1624796740.4202187
错误描述:'NoneType' object is not callable
类:main
方法:__init__
详细信息:
Traceback (most recent call last):
File "K:\xxx\main.py", line 115, in __get__
return self.__func(instance)
File "K:\xxx\main.py", line 150, in __init__
self.mainLoop()
TypeError: 'NoneType' object is not callable
------------------------------
2021-06-27 20:25:40,458 - Logger - ERROR
一个错误发生了,导致了程序异常退出.
详细信息:
Traceback (most recent call last):
File "K:\xxx\main.py", line 193, in <module>
app = main()
TypeError: 'NoneType' object is not callable
------------------------------
2021-06-27 20:25:40,476 - Logger - INFO
*** 程序终止运行 时间:Sun Jun 27 20:25:40 2021 ***
问题:
1.如何解决 'NoneType' object is not callable?
2.是否能不使用__get__而使用__call__来完成传入参数的问题?
3.(问题类似2)能否在__call__中获取实例和类?
4.在调试时发现加入__get__后__call__并不会执行(当然可能是执行前就出错弹出了),能否解释这个现象?
请回答问题时标注回答问题序号,谢谢!
本帖最后由 nahongyan1997 于 2021-6-27 21:51 编辑
我无视了你的四个问题,但是我觉得我应该解决了你真正的问题,请看代码:
class Demo:
# 定义装饰器
@classmethod
def widget(self,func):
# 使用闭包的方式
def a(self,*args,**kwargs):
print("in")
func(self)
print("out")
return a
class Demo1:
# 调用装饰器
@Demo.widget
def pp(self):
print("1")
app = Demo1()
app.pp()
打印结果:
in
1
out
解决你的问题花了我二十分钟的时间,这还{:10_256:} {:10_256:} 不给个最佳吗{:10_254:}
页:
[1]