简体   繁体   English

如何使用父类装饰器实现与实例相关的功能?

[英]How to implement instance-dependent functionality using parent class decorator?

I would like to implement a parent class decorator in my child class whose functionality depends on the state of the child class instance. 我想在子类中实现父类装饰器,该子类的功能取决于子类实例的状态。 I've tried coming at this problem from three different angles, none of which have worked: 我尝试从三个不同的角度来解决这个问题,但没有一个起作用:


Parent method 方法

If give_feedback is a static method, there's no self within the method. 如果give_feedback是静态方法,则该方法内没有self But if it's an instance method, there's no self within the namespace in which it's applied. 但是,如果它是一个实例方法,则在应用它的名称空间中就不会存在self

class Interface:
    def __init__(self, quiet=False):
        self.quiet = quiet

    def echo(self, text):
        if not self.quiet:
            print(text)

    def give_feedback(self, func):
        def wrapper(*args):
            print('Calling give_feedback.')
            self.echo(func(*args))
        return wrapper

class App(Interface):
    @Interface.give_feedback  # self not defined here.
    def app_func(self, num):
        feedback = 'Success with {num}'.format(num=num)
        return feedback

if __name__ == '__main__':
    a = App()
    a.app_func(3)

Parent class using __call__ (cf. link example_1) 使用__call__的父 (请参阅链接example_1)

Can't access the object from within __call__ . 无法从__call__内访问对象。

class Interface:
    # ...

    class give_feedback:
        def __init__(self, func):
            self.func = func

        def __call__(self, *args):
            print(
                'Calling {func}'.format(func=self.func)
            )
            instance = get_obj_instance(self.func)  # What is this?
            return instance.echo(self.func(instance, *args))

class App(Interface):
    # ...

if __name__ == '__main__':
    # ...

Parent descriptor (cf. link example_2) 父级描述符 (请参阅链接example_2)

Can access the object, but no arguments. 可以访问对象,但没有参数。

class Interface:
    # ...

    class give_feedback:
        # ...

        def __get__(self, instance, owner):
            print(
                'Getting {func} from {inst} of {ownr}'.format(
                    func=self.func, inst=instance, ownr=owner
                )
            )
            num = 2  # How to get num???
            return instance.echo(self.func(instance, num))

class App(Interface):
    # ...

if __name__ == '__main__':
    a = App()
    a.app_func  # No ability to pass parameters.

Is there a good way to do this? 有什么好方法吗?

Why not combine the 2nd and 3rd methods? 为什么不结合第二种方法和第三种方法? Use __get__ to get the class instance, and __call__ to decorate with echo . 使用__get__获取类实例,并使用__call__echo装饰。 Rather than returning app_func , return a new object that holds the instance and has the desired __call__ behavior. 而不是返回app_func ,而是返回一个保存实例并具有所需__call__行为的新对象。

class Interface:
    def __init__(self, quiet=False):
        self.quiet = quiet

    def echo(self, text):
        if not self.quiet:
            print(text)

    class give_feedback:
        def __init__(self, func):
            self.func = func

        def __get__(self, instance, owner):
            return self.InstHolder(instance, self.func)

        class InstHolder:
            def __init__(self, inst, func):
                self.inst = inst
                self.func = func

            def __call__(self, *args):
                return self.inst.echo(self.func(self.inst, *args))


class App(Interface):
    @Interface.give_feedback
    def app_func(self, num):
        feedback = 'Success with {num}'.format(num=num)
        return feedback


if __name__ == '__main__':
    a = App()
    a.app_func(3)
    a.quiet = True
    a.app_func(4)

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

相关问题 如何在“类”object 中实现“装饰器”功能? - How to implement “decorator” functionality in a “class” object? Python 在方法的装饰器中获取父 class 实例 - Python Get parent class instance in decorator of method 如何使用 class 装饰器计算实例方法调用 - How to count instance method calls with class decorator 如何调用其他class的装饰器(实例方法)? - How to call a decorator (instance method) of other class? 如何使用 arguments 作为 class 实现 Python 装饰器? - How to implement Python decorator with arguments as a class? 如何重新设计一个实例(在父类中)必须保证返回子实例的实例? - How to redesign an instance where common functionality (in a parent class) warrants returning instances of the children? 在父类方法上使用子类中指定的装饰器 - Using decorator specified in Child class on Parent class methods 如何在使用 `functools.wraps` 并保留对装饰实例的访问权时创建一个带参数的装饰器类 - How to Create a Decorator Class that takes Arguments while Using `functools.wraps` and Preserving Access to the Decorated Instance 如何继承父类的所有功能? - How to inherit all functionality of a parent class? 使用父类的装饰器方法转换类方法 - transform class methods using parent class' decorator method
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM