简体   繁体   English

为什么这个 class 装饰器不装饰?

[英]Why does this class decorator not decorate?

At a little bit of a loss here.在这里有点失落。 I'm attempting to decorate all methods of a class, and using the solution here .我正在尝试装饰 class 的所有方法,并在此处使用解决方案。 I feel like I have all the pieces (see below) yet when I initialize the class/call its methods, nothing happens.我觉得我拥有所有的部分(见下文),但是当我初始化类/调用它的方法时,什么也没有发生。

As a toy example, I've got the function decorator作为一个玩具示例,我有 function 装饰器

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

and the class decorator和 class 装饰器

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

and the toy class和玩具 class

@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

yet when I initialize the class然而,当我初始化 class

c = Car()

or call its methods, they aren't decorated.或调用它的方法,它们没有被装饰。 What gives?是什么赋予了? I feel like I must be missing something trivial.我觉得我一定错过了一些微不足道的东西。

inspect.ismethod checks for bound method objects - the kind of thing you get from Car().drive , not Car.drive . inspect.ismethod检查绑定的方法对象——你从Car().drive得到的东西,而不是Car.drive Car.drive is a function object. Car.drive是 function object。

The code you were looking at was written for Python 2 only.您正在查看的代码仅为 Python 2 编写。 Methods work a bit differently on Python 2.方法在 Python 2 上的工作方式略有不同。

Okay, it works if I change inspect.ismethod to inspect.isfunction .好的,如果我将inspect.ismethod更改为inspect.isfunction就可以了。

I still don't 100% get it, since我仍然没有 100% 明白,因为

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

prints印刷

__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>>

as I would expect.正如我所料。

Edit: user2357112 supports Monica clarified here .编辑:user2357112 支持 Monica 在这里澄清。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM