zoukankan      html  css  js  c++  java
  • python装饰器 和单例模式

    闭包:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包。

    内嵌函数:

     1 def foo():
     2     def bar():
     3         print('bar() called')
     4     print ('foo() called')
     5     return bar
     6 
     7 >>>f = foo()
     8 foo() called
     9 >>>f()
    10 bar() called

    相当于:

    1 def foo():
    2     def bar():
    3         print('bar() called')
    4     print ('foo() called')
    5     return bar()
    6 
    7 >>>foo()
    8 foo() called
    9 bar() called

    装饰器:是一个实现了给现有函数添加装饰功能的函数,就是把原来的函数给包了起来,在不改变原函数代码的情况下,在外面起到了装饰作用

    1. 它的参数是需要被装饰的函数
    2. 返回值是新定义的一个包装了原有函数的函数。

    在被装饰的函数前使用@符号指定装饰器,在运行程序的时候,Python解释器会根据@标注自动生成装饰器函数,并调用装饰器函数。

    带参数的函数:

     1 import time
     2 
     3 def timer(func):
     4  '''统计函数运行时间的装饰器'''
     5  def wrapper(*args, **kwargs):
     6   start = time.time()
     7   func(*args, **kwargs)
     8   end = time.time()
     9   used = end - start
    10   print(f'{func.__name__} used {used}')
    11  return wrapper
    1. wrapper使用了通配符,*args代表所有的位置参数,**kwargs代表所有的关键词参数。这样就可以应对任何参数情况。
    2. wrapper调用被装饰的函数的时候,只要原封不动的把参数再传递进去就可以了。

    函数返回值:

      如果被装饰的函数func有返回值,wrapper也只需把func的返回值返回就可以了。

     1 import time
     2 
     3 def timer(func):
     4  '''统计函数运行时间的装饰器'''
     5  def wrapper(*args, **kwargs):
     6   start = time.time()
     7   ret_value = func(*args, **kwargs)
     8   end = time.time()
     9   used = end - start
    10   print(f'{func.__name__} used {used}')
    11   return ret_value
    12  return wrapper
    13 
    14 @timer
    15 def add(num1, num2):
    16  return num1 + num2
    17 
    18 sum = add(5, 8)
    19 print(sum)

    代码调试:

      现在我们来创建一个装饰器:它会打印函数的参数,以及返回值。

      如果你有实际项目经验,你一定会知道这个很有用。这不就是自动打印日志嘛!

     1 def debug(func):
     2     def wrapper_debug(*args, **kwargs):
     3         print(f'{func.__name__}:{args}, {kwargs}')
     4         ret_val = func(*args, **kwargs)
     5         print(f'return: {ret_val}')
     6         return ret_val
     7     return wrapper_debug
     8 
     9 @debug
    10 def add(a, b):
    11     return a + b
    12 
    13 add(1, 3)
    14 add(2, 3)
    15 add(4, 3)

    装饰器模版:

    1 def decorator(func):
    2     def wrapper_decorator(*args, **kwargs):
    3         #调用前操作
    4         ret_val = func(*args, **kwargs)
    5         #调用后操作
    6         return ret_val
    7     return wrapper_decorator

    按照这个模板:

    1. 修改装饰器的名字,把decorator替换为具体的名字。
    2. 在注释“调用前操作”的地方写自己想写的代码

    在注释“调用后操作”的地方写自己想写的代码。

  • 相关阅读:
    【Android Developers Training】 73. 布局变化的动画
    【Android Developers Training】 72. 缩放一个视图
    【Android Developers Training】 71. 显示翻牌动画
    svn更改地址怎么办
    python学习手册
    failed to bind pixmap to texture
    Ubuntu 12.04安装Google Chrome
    svn update 时总是提示 Password for '默认密钥' GNOME keyring: 输入密码
    重设SVN 的GNOME keyring [(null)] 的密码
    Nginx + uWSGI + web.py 搭建示例
  • 原文地址:https://www.cnblogs.com/gujunjie-study-time/p/15099250.html
Copyright © 2011-2022 走看看