简体   繁体   中英

Python staticmethod decorator with inheritance

My case:

class BaseClass:

    @staticmethod
    def dummy_decorator(fnc):
        def wrapper():
            print('Im so dummy')
        return wrapper


class InheritedClass(BaseClass):
    def __init__(self):
        pass

    def anymethod(self):
        print('hello world')

When I look at dir() , I see my staticmethod

>>> c = InheritedClass()
>>> dir(c)
['__doc__', '__init__', '__module__', 'anymethod', 'dummy_decorator']

Also, I can use my dummy operator as simple staticmethod inside new class. But when I try to use it as decorator -- I get error

class InheritedClass(BaseClass):
    def __init__(self):
        pass

    @dummy_decorator
    def anymethod(self):
        print('hello world')

>>> NameError: name 'dummy_decorator' is not defined

Why it works so? I know, that if I change @dummy_decorator to @BaseClass.dummy_decorator -- everything will work, but why I can't use decorator without ref to parent class?

The reason why is baecause it is a static method, it belongs to the class as you have figured out when you put @BaseClass.dummy_decorator and it worked.

It is an attribute of the class so you can't just refer to it by dummy_decorator unless you move it out of the class or save it into the global namespace

To understand this properly, you need to understand how class definitions work. In a nutshell, everything inside a class block is executed just like regular Python code. Every name that has been created inside that class block (eg def or variable assignments) are then wrapped up at the end of the class block and become attributes of the new class object. It goes something like:

# START CAPTURE
def __init__(self):
    pass

foo = 'bar'
# END CAPTURE

InheritedClass = # OBJECT WITH ATTRIBUTES "CAPTURED" ABOVE AND ADDITIONAL MAGIC

So, any code within the class block is just regular Python code. It hasn't "inherited" anything yet. That's the "additional magic" applied to the resulting class object at the end of the class block. And since there's no global " dummy_decorator " name defined, you can't call it by that name. It exists as " BaseClass.dummy_decoator ", same as it would outside any class block.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM