简体   繁体   中英

Is this a decorator of some type in Python?

I have been reading through some code and came across this below.

I do not understand whether the @SdServer.appId(APP_ID) is a decorator. It has the @ from a decorator, but the class method appId does not look like a decorator syntax that I am used to. I do not understand what this is doing.

The print statements that I include at the end looking for the appID in the SdApp class returns this:

SdApp class instance ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'request'] 

SdApp instance request ['__call__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__func__', '__ge__', '__get__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__'] 

method list ['request']

The code

APP_ID = 'oA'

class SdServer(object):
    APP_ID_HANDLERS = {}

    def __init__(self, originator):
        self.originator = originator

    @classmethod
    def appId(cls, appId):
        def _handler(f):
            cls.APP_ID_HANDLERS[appId] = f
            return f

        return _handler


@SdServer.appId(APP_ID)
class SdApp(object):
    @classmethod
    def request(cls, originator, body=None):
        try:
            print(cls)
        except OException as e:
            log.error('Cannot process request: %s', e)

# me trying to figure out what it is doing below

first = SdApp()

print('SdApp class instance', dir(first), '\n')
print('SdApp instance request', dir(first.request), '\n')

method_list = [func for func in dir(SdApp) if callable(getattr(SdApp, func)) and not func.startswith("__")]

print('method list', method_list)

The classmethod itself is not the decorator but rather its return value. In your example the @SdServer.appId(APP_ID) will call the classmethod and use the result as a decorator. Following your example further this would be the _handler function which seems to register the decorated class with the SdServer class. This returned decorator contains closures over the cls and the appId variables hence the somewhat convoluted implementation.

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