• python 装饰器应用


    1 注册回调函数

    下面这个示例展示了通过URL的路由来调用相关注册的函数示例:

    class MyApp():

        def __init__(self):

            self.func_map = {}

     

        def register(self, name):

            def func_wrapper(func):

                self.func_map[name] = func

                return func

            return func_wrapper

     

        def call_method(self, name=None):

            func = self.func_map.get(name, None)

            if func is None:

                raise Exception("No function registered against - " + str(name))

            return func()

     

    app = MyApp()

     

    @app.register('/')

    def main_page_func():

        return "This is the main page."

     

    @app.register('/next_page')

    def next_page_func():

        return "This is the next page."

     

    print app.call_method('/')

    print app.call_method('/next_page')

    注意:
    1)上面这个示例中,用类的实例来做decorator。
    2)decorator类中没有__call__(),但是wrapper返回了原函数。所以,原函数没有发生任何变化。

    2 打印日志

    from functools import wraps

    import inspect

    def get_line_number():

        return inspect.currentframe().f_back.f_back.f_lineno

    def logger(loglevel):

        def log_decorator(fn):

            @wraps(fn)

            def wrapper(*args, **kwargs):

                ts = time.time()

                result = fn(*args, **kwargs)

                te = time.time()

                print "function   = " + fn.__name__,

                print "    arguments = {0} {1}".format(args, kwargs)

                #print "    return    = {0}".format(result)

                print "    time      = %.6f sec" % (te-ts)

                if (loglevel == 'debug'):

                    print "    called_from_line : " + str(get_line_number())

                return result

            return wrapper

        return log_decoratorspam(1,2,3)

    3 调用追踪

    import sys,os,linecache

    def trace(f):

      def globaltrace(frame, why, arg):

        if why == "call": return localtrace

        return None

      def localtrace(frame=1, why=2, arg=4):

        if why == "line":

          # record the file name and line number of every trace

          filename = frame.f_code.co_filename

          lineno = frame.f_lineno

          bname = os.path.basename(filename)

          print "{}({}): {}".format(  bname,

                        lineno,

                        linecache.getline(filename, lineno)),

        return localtrace

      def _f(*args, **kwds):

        sys.settrace(globaltrace)

        result = f(*args, **kwds)

        sys.settrace(None)

        return result

      return _f

    @trace

    def xxx():

      a=1

      print a

    xxx() #调用

    4 单例模式

    # coding=utf-8
    # 测试utf-8编码
    # 单例装饰器
    import sys
    reload(sys)
    sys.setdefaultencoding('utf-8')
     
    # 使用装饰器实现简单的单例模式
    def singleton(cls):
        instances = dict()  # 初始为空
        def _singleton(*args, **kwargs):
            if cls not in instances:  #如果不存在, 则创建并放入字典
                instances[cls] = cls(*args, **kwargs)
            return instances[cls]
        return _singleton
     
    @singleton
    class Test(object):
        pass
    if __name__ == '__main__':
        t1 = Test()
        t2 = Test()
        # 两者具有相同的地址
        print t1
        print t2
  • 相关阅读:
    java JDBC DAO ORM Domain
    《硅谷钢铁侠-- 埃隆·马斯克的冒险人生》
    在启动MYSQL时出现问题:“ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)”
    使用IntelliJ IDEA开发java web
    [django]用日期来查询datetime类型字段
    2020/5/31
    图解排序算法(三)之堆排序
    图解排序算法(二)之希尔排序
    图解排序算法(一)之3种简单排序(选择,冒泡,直接插入)
    Oracle约束(Constraint)详解
  • 原文地址:https://www.cnblogs.com/sysnap/p/6603902.html
Copyright © 2020-2023  润新知