zoukankan      html  css  js  c++  java
  • 3、黑魔法杂货铺

    装饰器

    # 验证session的装饰器, 在web框架中可以重复使用
    def authForm(func):
        def wrapper(request, *args, **kwargs):
            if request.session.get['username']:
                return func(request, *args, **kwargs)
            else:
                return render(request, 'login.html')
    
        return wrapper
    
    # 为函数执行前和函数执行后增加功能的装饰器
    def filter(before_func, after_func):
        def outer(main_func):
            def wrapper(request, *args, **kwargs):
                before_result = before_func(request, *args, **kwargs)
                if before_func != None:
                    return before_result
    
                main_result = main_func(request, *args, **kwargs)
                if main_result != None:
                    return main_result
    
                after_result = after_func(request, *args, **kwargs)
                if after_result != None:
                    return after_result
    
            return wrapper()
    
        return outer()
    
    #==========两个实用的Python的装饰器实例=========#
    # 第一式:超时函数
    '''这个函数的作用在于可以给任意可能会hang住的函数添加超时功能,
    这个功能在编写外部API调用 、网络爬虫、数据库查询的时候特别有用。timeout装饰器的代码如下:'''
    # 下面会用到signal, functools两个库, 定义一个Exception,后面超时抛出
    class TimeoutError(Exception):
        pass
    
    def timeout(seconds, error_message = 'Function call timed out'):
    
        def decorated(func):
    
            def _handle_timeout(signum, frame):
                raise TimeoutError(error_message)
    
            def wrapper(*args, **kwargs):
                signal.signal(signal.SIGALRM, _handle_timeout)
                signal.alarm(seconds)
                try:
                    result = func(*args, **kwargs)
                finally:
                    signal.alarm(0)
                return result
            return functools.wraps(func)(wrapper)
        return decorated
    
    # 使用:限定下面的slowfunc函数如果在5s内不返回就强制抛TimeoutError Exception结束
    @timeout(5)
    def slowfunc(sleep_time):
        time.sleep(sleep_time)  #这个函数就是休眠sleep_time秒
    
    slowfunc(3)     #sleep 3秒,正常返回没有异常
    slowfunc(10)    #被终止
    
    # 第二式:Trace函数
    '''有时候出于演示目的或者调试目的,我们需要程序运行的时候打印出每一步的运行顺序和调用逻辑。
    类似写bash的时候的bash -x调试功能,然后Python解释器并没有内置这个十分有用的功能。
    Trace装饰器的代码如下:'''
    def trace(f):
    
        def globaltrace(frame, why, arg):
            if why == "call":
                return localtrace
            return None
    
        def localtrace(frame, why, arg):
            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():
        print(1)
        print(22)
        print(333)
    decorator

    闭包

    def make_addr(adden):
        def addr(args):
            return args + adden
        return addr
    
    m1 = make_addr(23)
    m2 = make_addr(44)
    
    >>> print(m1(100))
    123
    >>> print(m2(100))
    144
    closure

    反射

    class Student(object):
    
        @property
        def birth(self):
            return self._birthday
    
        @birth.setter
        def birth(self, birthday):
            self._birthday = birthday
    
    s = Student()
    s.birth = 29
    print(s.birth)
    
    
    # 下面这个例子更加清楚简洁的使用了__getattr__和__setattr__
    # JsonDict继承dict类,重写dict类__getattr__和__setattr__方法
    class JsonDict(dict):
    
        def __init__(self, **kw):
            super().__init__(**kw)
    
        def __getattr__(self, attr):
            try:
                return self[attr]
            except KeyError:
                raise AttributeError(r"'JsonDict' object has no attribute '%s'" % attr)
    
        # 可以重写dict,使之通过"."调用
        def __setattr__(self, attr, value):
            self[attr] = value
    
    j = JsonDict(name='python', age='28')
    print(j)
    print(j.name)
    print(j.age)
    
    """现在很多网站都搞REST API,比如新浪微博、豆瓣啥的,调用API的URL类似:
    http://api.server/user/friends
    http://api.server/user/timeline/list
    如果要写SDK,给每个URL对应的API都写一个方法,那得累死,而且,API一旦改动,SDK也要改。
    利用完全动态的__getattr__,我们可以写出一个链式调用:"""
    
    class Chain(object):
    
        def __init__(self, path=''):
            self._path = path
    
        # 所有Chain.xx的方法都能通过,可以使用raise AttributeError可以限制传入的参数
        def __getattr__(self, path):
            return Chain('%s/%s' % (self._path, path))
    
        def __str__(self):
            return self._path
    
        __repr__ = __str__
    
        def test(self):
            pass
    
    
    # 测试结果如下:
    """
    >>> Chain().status.user.timeline.list
    '/status/user/timeline/list'
    >>> Chain(http://api.server).status.user.timeline.list
    'http://api.server/status/user/timeline/list'
    """
    
    c = Chain()
    print(hasattr(c, 'best'))
    print(getattr(c, 'best'))
    reflex
  • 相关阅读:
    分数加减法
    两点距离
    1的个数
    Swift 了解(1)
    ARC快速入门
    ARC基本概念
    autorelease注意事项
    autorelease基本使用
    NSTimer的使用
    如何监听控件的行为
  • 原文地址:https://www.cnblogs.com/raykuan/p/6130015.html
Copyright © 2011-2022 走看看