'Some problems about Python inherited classmethod

I have this code:

from typing import Callable, Any


class Test(classmethod):
    def __init__(self, f: Callable[..., Any]):
        super().__init__(f)

    def __get__(self,*args,**kwargs):
        print(args)  # why out put is (None, <class '__main__.A'>) where form none  why no parameter 123
        # where was it called
        return super().__get__(*args,**kwargs)


class A:
    @Test
    def b(cls,v_b):
        print(cls,v_b)

A.b(123)

Why the output is (None, <class '__main__.A'>)? Where did None come form and why is it not the parameter 123, which is the value I called it with?



Solution 1:[1]

You can apply multiple decorators on the same function, for example,

  • first (and outer) decorator could be a classmethod
  • and the second (doing your stuff) could define a wrapper, where you could accept your arguments as usual
In [4]: def test_deco(func):
   ...:     def wrapper(cls, *args, **kwds):
   ...:         print("cls is", cls)
   ...:         print("That's where 123 should appear>>>", args, kwds)
   ...:         return func(cls, *args, **kwds)
   ...: 
   ...:     return wrapper
   ...: 
   ...: 
   ...: class A:
   ...:     @classmethod
   ...:     @test_deco
   ...:     def b(cls, v_b):
   ...:         print("That's where 123 will appear as well>>>", v_b)
   ...: 
   ...: 
   ...: A.b(123)
cls is <class '__main__.A'>
That's where 123 should appear>>> (123,) {}
That's where 123 will appear as well>>> 123

In [5]: 

It's too much trouble to use two at a time i want only use one like it

It is possible to define a decorator applying a couple of other decorators:

def my_super_decorator_doing_everything_at_once(func):
    return classmethod(my_small_decorator_doing_almost_everything(func))

That works because decorators notation

@g
@f
def x(): ...

is a readable way to say

def x(): ...
x = g(f(x))

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 BrokenBenchmark