Python decorator best practice, using a class vs a function

前端 未结 4 1908
走了就别回头了
走了就别回头了 2020-12-04 06:45

As I\'ve understood it there are two ways to do a Python decorator, to either use the __call__ of a class or to define and call a function as the decorator. Wha

4条回答
  •  广开言路
    2020-12-04 06:51

    There are two different decorator implementations. One of these uses a class as a decorator and the other uses a function as a decorator. You must choose the preferred implementation for your needs.

    For example, if your decorator does a lot of work then you can use class as a decorator, like this:

    import logging
    import time
    import pymongo
    import hashlib
    import random
    
    DEBUG_MODE = True
    
    class logger(object):
    
            def __new__(cls, *args, **kwargs):
                    if DEBUG_MODE:
                            return object.__new__(cls, *args, **kwargs)
                    else:
                            return args[0]
    
            def __init__(self, foo):
                    self.foo = foo
                    logging.basicConfig(filename='exceptions.log', format='%(levelname)s %   (asctime)s: %(message)s')
                    self.log = logging.getLogger(__name__)
    
            def __call__(self, *args, **kwargs):
                    def _log():
                            try:
                                   t = time.time()
                                   func_hash = self._make_hash(t)
                                   col = self._make_db_connection()
                                   log_record = {'func_name':self.foo.__name__, 'start_time':t, 'func_hash':func_hash}
                                   col.insert(log_record)
                                   res = self.foo(*args, **kwargs)
                                   log_record = {'func_name':self.foo.__name__, 'exc_time':round(time.time() - t,4), 'end_time':time.time(),'func_hash':func_hash}
                                   col.insert(log_record)
                                   return res
                            except Exception as e:
                                   self.log.error(e)
                    return _log()
    
            def _make_db_connection(self):
                    connection = pymongo.Connection()
                    db = connection.logger
                    collection = db.log
                    return collection
    
            def _make_hash(self, t):
                    m = hashlib.md5()
                    m.update(str(t)+str(random.randrange(1,10)))
                    return m.hexdigest()
    

提交回复
热议问题