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. 在注释“调用前操作”的地方写自己想写的代码

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

  • 相关阅读:
    Git使用笔记
    javascript获取表单值的7种方式
    javascript里阻止事件冒泡
    PHP面向对象04_串行化
    MySQL数据库锁定机制
    SAP R3和JAVA交换数据之JCO
    @XStreamAlias使用
    JCO 自定义DestinationDataProvider
    IBM websphere MQ 消息发送与获取
    WebSphere MQ 入门指南
  • 原文地址:https://www.cnblogs.com/gujunjie-study-time/p/15099250.html
Copyright © 2011-2022 走看看