git.net

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

How do I give a decorator acces to the class of a decorated function


On 4/09/19 17:46, Peter Otten wrote:
> Antoon Pardon wrote:
>
>> What I am trying to do is the following.
>>
>> class MyClass (...) :
>>     @register
>>     def MyFunction(...)
>>         ...
>>
>> What I would want is for the register decorator to somehow create/mutate
>> class variable(s) of MyClass.
>>
>> Is that possible or do I have to rethink my approach?
> If you are willing to delegate the actual work to the metaclass call: 
>
> def register(f):
>     f.registered = True
>     return f
>
> def registered(name, bases, namespace):
>     namespace["my_cool_functions"] = [
>         n for n, v in namespace.items()
>         if getattr(v, "registered", False)
>     ]
>     return type(name, bases, namespace)
>
> class MyClass(metaclass=registered) :
>     @register
>     def foo(self):
>         pass
>     @register
>     def bar(self):
>         pass
>     def other(self):
>         pass
>
> print(MyClass.my_cool_functions)

I have been playing with this idea and it looks promising. I was wondering
about two points.

1) I guess I can add extra methods to my class through the metaclass by
   having something like the following in the registered function:

def registered(name, bases, namespace):
    namespace["my_cool_functions"] = [
        n for n, v in namespace.items()
        if getattr(v, "registered", False)
    ]
    namespace["__getitem__"] = lambda self, index: self.my_cool_functions[index]

2) Is it possible to make MyClass automatically a subclass of an other class
   through the metaclass?

-- 
Antoon.