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

 

posted @ 2017-03-23 10:46  sysnap  阅读(244)  评论(0编辑  收藏  举报