【问题标题】:Why does this class decorator not decorate?为什么这个类装饰器不装饰?
【发布时间】:2021-05-10 05:47:46
【问题描述】:

这里有点失落。我正在尝试装饰一个类的所有方法,并使用解决方案here。我觉得我已经拥有了所有的部分(见下文),但是当我初始化类/调用它的方法时,什么都没有发生。

作为一个玩具示例,我有函数装饰器

def my_decorator(func):
    def wrapper(*args):
        print("Something is happening before the function is called.")
        return func(*args)
        print("Something is happening after the function is called.")
    return wrapper

和类装饰器

def for_all_methods(decorator):
    import inspect
    def decorate(cls):
        for name, fn in inspect.getmembers(cls, inspect.ismethod):
            print(name, fn)
            setattr(cls, name, decorator(fn))
        return cls
    return decorate

还有玩具课

@for_all_methods(my_decorator)
class Car:
    def __init__(self):
        self.wheels = 4
        self.price=20000
        self.mileage = 0
    
    def drive(self, miles):
        self.mileage += miles
    
    def depreciate(self):
        self.price-=0.1*self.mileage

当我初始化类时

c = Car()

或调用它的方法,它们没有被装饰。是什么赋予了?我觉得我一定错过了一些微不足道的事情。

【问题讨论】:

  • print(name, fn) 打印出预期的结果吗?
  • 不,但如果我打电话给for name, fn in inspect.getmembers(Car(), inspect.ismethod): print(name, fn),我会得到预期的结果。

标签: python decorator wrapper


【解决方案1】:

inspect.ismethod 检查绑定的方法对象——你从Car().drive 得到的东西,而不是Car.driveCar.drive 是一个函数对象。

您正在查看的代码仅针对 Python 2 编写。方法在 Python 2 上的工作方式略有不同。

【讨论】:

  • 不知何故,如果我将其更改为inspect.isfunction,它就会起作用。我仍然不完全明白,因为for name, fn in inspect.getmembers(Car(), inspect.ismethod): print(name, fn) 打印出我所期望的。
  • @ahalev: inspect.getmembers(Car(), ...)inspect.getmembers(Car, ...) 是一个非常不同的电话。
【解决方案2】:

好的,如果我将inspect.ismethod 更改为inspect.isfunction,它会起作用。

我仍然没有 100% 明白,因为

for name, fn in inspect.getmembers(Car(), inspect.ismethod):
     print(name, fn)

打印

__init__ <bound method my_decorator.<locals>.wrapper of <__main__.Car object at 0x7fb577e30cf8>>
depreciate <bound method my_decorator.<locals>.wrapper of <__main__.Car object at 0x7fb577e30cf8>>
drive <bound method my_decorator.<locals>.wrapper of <__main__.Car object at 0x7fb577e30cf8>>

正如我所料。

编辑:user2357112 支持莫妮卡澄清here

【讨论】:

    猜你喜欢
    • 2016-11-25
    • 2019-06-28
    • 2018-03-27
    • 2011-09-03
    • 2012-03-22
    • 2020-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多