Philipp Stephan
Philipp Stephan

Reputation: 392

Use inherited method from parent class as decorator on child classes method

I am trying to set up a method in a class A that can be used in a child class B as a decorator for a method. I want to map arguments to these functions depending on some instance attributes.

Doing this within the same class works fine:

class Class:
    def __init__(self):
        self.mapper = "mapped "

    def map_arg(func):
        def mapped_func(self, unmapped_value):
            mapped_value = self.mapper + unmapped_value
            return func(self, mapped_value)
        return mapped_func

    @map_arg
    def func(self, mapped_value):
        print(mapped_value)

obj = Class()
obj.func("value")

prints mapped value. But when I try to inherit the decorator, it throws a NameError

class ParentClass:
    def map_arg(func):
        def mapped_func(self, unmapped_value):
            mapped_value = self.mapper + unmapped_value
            return func(self, mapped_value)
        return mapped_func

class ChildClass(ParentClass):
    def __init__(self):
        self.mapper = "mapped "

    @map_arg
    def func(self, mapped_value):
        print(mapped_value)

obj = ChildClass()
obj.func("value")
Traceback (most recent call last):
  File "/tmp/decorator.py", line 43, in <module>
    class ChildClass(ParentClass):
  File "/tmp/decorator.py", line 47, in ChildClass
    @map_arg
NameError: name 'map_arg' is not defined

I've also tried using @super().map_arg, but that's a syntax error. I guess its just easier to call self.map_arg within the function instead of wrapping it in a decorator. But would there be a way to make it work?

Upvotes: 0

Views: 117

Answers (1)

Riccardo Bucco
Riccardo Bucco

Reputation: 15364

You just need to use the name off you parent class:

class ChildClass(ParentClass):
    def __init__(self):
        self.mapper = "mapped "
    @ParentClass.map_arg
    def func(self, mapped_value):
        print(mapped_value)

Upvotes: 1

Related Questions