Python 如何装饰类中的所有方法?我可以装饰一下教室吗?

Python 如何装饰类中的所有方法?我可以装饰一下教室吗?,python,Python,我有几个类,它们的实现名称相同,但实现方式不同。我想装饰一些类中的所有方法,但其他类中没有。我考虑过继承,但是有些类有一些方法不需要修饰。问题是,我不想一个接一个地修饰方法,有些类需要由同一个修饰器修饰,有什么解决方案可以解决吗?您可以启动所有需要用前缀修饰的方法,然后使用如下方式: class Xobject(object): def __init__(self, decorator): for method_name in dir(self):

我有几个类,它们的实现名称相同,但实现方式不同。我想装饰一些类中的所有方法,但其他类中没有。我考虑过继承,但是有些类有一些方法不需要修饰。问题是,我不想一个接一个地修饰方法,有些类需要由同一个修饰器修饰,有什么解决方案可以解决吗?

您可以启动所有需要用前缀修饰的方法,然后使用如下方式:

class Xobject(object):

    def __init__(self, decorator):
        for method_name in dir(self):
            if method_name.startswith("dec_"):
                attr = getattr(self, method_name)
                wrapped = decorator(attr)
                setattr(self, method_name, wrapped)

    def dec_me_1(self):
        print("In dec_me1")
        return 0

    def dec_me_2(self):
        print("In dec_me2")
        return 1


def decorator(func):

    def wrapped(*args):
        print("TEST")
        return func(*args)

    return wrapped


x = Xobject(decorator)

x.dec_me_1()
x.dec_me_2()
def wrapper(func):
    def inner(*args, **kwargs):
        print "%s was called" func.__name__
        return func(*args, **kwargs)
    return inner

class A(object):
    def foo(self):
        print "foo called"
    def bar(self):
        print "BAR CALLED"

class B(A):
    @wrapper
    def foo(self):
        super(B, self).foo()

class C(A):
    @wrapper
    def bar(self):
        super(C, self).bar()

Stick = A()
Dave = B()
Jupiter = C()

Jupiter.foo() #prints "foo called"
Jupiter.bar() #prints "bar wrapped" and "BAR CALLED"
更新

您可以通过下面的函数来装饰类。在使用Python时,您应该知道Python中的
class
也是对象,因此您可以更改它并将其传递给其他函数

def decorator(func):

    def wrapped(*args):
        print("TEST")
        return func(*args)

    return wrapped


def decorate_object(p_object, decorator):
    for method_name in dir(p_object):
        if method_name.startswith("dec_"):
            attr = getattr(p_object, method_name)
            wrapped = decorator(attr)
            setattr(p_object, method_name, wrapped)

decorate_object(Xobject, decorator)

x = Xobject()

x.dec_me_1()
x.dec_me_2()
您也可以用同样的方式装饰已实例化的对象:

x = Xobject()

x.dec_me_1()
x.dec_me_2()

decorate_object(x, decorator)

x.dec_me_1()
x.dec_me_2()

我相信有几种方法可以做到这一点,但主要的主要选择是:

  • 创建一个自定义元类,其中
    \uuuuu new\uuuuu
    方法在属性字典中迭代,标识方法并修饰它们。有关Python元类编程的示例,请参见。缺点:这可能比我们想在这里讨论的更复杂
  • 在常规类的
    \uuuu init\uuu
    方法中执行相同的操作。缺点:它只装饰实例方法,不装饰类或静态方法,而且速度较慢,因为每次创建新实例时它都会运行
  • 课外活动:

    class Foo(object):
      def bar(self):
        print 'bar'
    
    for name, ref in vars(Foo):
      if callable(ref): ...
    
    缺点:你只有一次机会把它做好:在导入时。子类不会被修改

  • 在类级装饰器中完成。我认为这和课外做同样的缺点


在某些情况下,你必须明确哪些内容被包装,哪些内容没有包装

如果我理解正确,我想你可以这样做:

class Xobject(object):

    def __init__(self, decorator):
        for method_name in dir(self):
            if method_name.startswith("dec_"):
                attr = getattr(self, method_name)
                wrapped = decorator(attr)
                setattr(self, method_name, wrapped)

    def dec_me_1(self):
        print("In dec_me1")
        return 0

    def dec_me_2(self):
        print("In dec_me2")
        return 1


def decorator(func):

    def wrapped(*args):
        print("TEST")
        return func(*args)

    return wrapped


x = Xobject(decorator)

x.dec_me_1()
x.dec_me_2()
def wrapper(func):
    def inner(*args, **kwargs):
        print "%s was called" func.__name__
        return func(*args, **kwargs)
    return inner

class A(object):
    def foo(self):
        print "foo called"
    def bar(self):
        print "BAR CALLED"

class B(A):
    @wrapper
    def foo(self):
        super(B, self).foo()

class C(A):
    @wrapper
    def bar(self):
        super(C, self).bar()

Stick = A()
Dave = B()
Jupiter = C()

Jupiter.foo() #prints "foo called"
Jupiter.bar() #prints "bar wrapped" and "BAR CALLED"

请重新格式化您的问题,并澄清如下观点:“但是有些类的方法不需要修饰”与“我想修饰类中的所有方法”——这听起来像是一个悖论,也有许多语法错误。谢谢提醒我。问题是我不想一个接一个地修饰方法,有些类需要用同一个装饰器来修饰它们。你知道吗,你可以用装饰器来修饰整个类<代码>@decorator;类A(对象):…我不知道,我只是decorator可以将一个类作为param,有没有任何例子可以将decorator与类一起使用?如果我的类没有init方法,它们实际上从同一个类继承,但我不想更改基类。可以用“某物”来修饰类的每个方法使用分离的函数并将类或对象传递给它,这需要进行修饰。我已经用例子更新了我的答案,很有效,谢谢。我知道怎么修理它!:)是的,我也考虑过元类,它很复杂,很难阅读,所以也许我会一个接一个地添加装饰器。非常感谢。