码迷,mamicode.com
首页 > 编程语言 > 详细

python函数下篇装饰器和闭包,外加作用域

时间:2017-06-20 01:05:18      阅读:301      评论:0      收藏:0      [点我收藏+]

标签:方式   action   参数   start   app   空间   name   lis   名称   

装饰器和闭包的基础概念

装饰器是一种设计模式能实现代码重用,经常用于查日志,性能测试,事务处理等,抽离函数大量不必的功能。 装饰器:
1、装饰器本身是一个函数,用于装饰其它函数:
2、功能:增强被装饰函数的功能。

装饰器需要遵循的原则

1.不修改被装饰函数的源代码(开放封闭原则) 2.为被装饰函数添加新功能后,不修改被装饰函数的调用方式

装饰器 = 高阶函数+函数嵌套+闭包

高阶函数

1.函数接受的参数是一个函数名 2.函数的返回值是一个函数名 3.只有上述条件满足一个就是高阶函数

def foo():
    print(高阶函数实例,被调用的函数)

def func(foo):
    print(调用上面的函数)
    foo()

func(foo)

把函数名当做参数传给告诫函数,告诫函数直接返回函数名

import time
def foo():
    print(from the foo)

def timmer(func):
    start_time = time.time()
    return func
    stop_time = time.time()
    print(函数%s运行时间是%s)%(func,stop_time - start_time)

foo = timmer(foo)
foo()

高阶函数总结 1.函数接收的参数是一个函数名
作用:在不修改函数源代码的前提下,为函数添加新功能
不足:会改变函数的调用方式

2.函数的返回值是一个函数名
作用:不修改函数的调用方式
不足:不能添加新功能

嵌套函数

def father(name):
    print(from father %s%name)
    def son():
        print(from son)
        def grandson():
            print(from grandson)
        grandson()
    son()
father(逗逼)

闭包函数:函数在嵌套环境中,如果在内层函数里,对外层函数作用域中的变量进行引用,在外层函数返回后内层函数依然可以使用外层函数中的变量,这种变量就构成了内层函数可以使用的环境。所以闭包对隐藏状态,以及在函数对象和作用域中随意切换,一个函数可以发挥N种功用

def f1(x):
def f2(y):
return y ** x
return f2
f1(4)

f3=f1(3)
type(f3)

f3(4)

def startPos(m,n):
def newPos(x,y):
print(‘‘The old position is (%d,%d), and the new position is (%d,%d)"%(m,n,m+x,n+y))
return newPos

action = startPos(10,10)
action(1,2)
action(-1,3)

#结果
<function f1.<locals>.f2 at 0x02125270>
<class function>
64
The old position is (10,10),and the new position is (11,12)
The old position is (10,10),and the new position is (9,13)

无参装饰器

无参装饰器 = 高级函数 + 函数嵌套 基本框架

#这就是一个实现一个装饰器最基本的架子
def time(func):
    def wrapper():
        func()
    return wrapper

加上参数

def timer(func):
    def wrapper(*args,**kwargs):
        func(*args,**kwargs)
    return wrapper

加上功能

import time
def timer(func):
    def wrapper(*args,**kwargs):
        start_time = time.time()
        func(*args,**kwargs)
        stop_time = time.time()
        print(函数[%s],运行时间是[%s]%(func,stop_time-start_time))
    return wrapper

加上返回值

import time
def timer(func):
    def wrapper(*args,**kwargs):
        start_time = time.time()
        res = func(*args,**kwargs)
        stop_time = time.time()
        print(函数[%s],运行时间是[%s]%(func,stop_time-start_time))
        return res
    return wrapper

使用装饰器

def cal(arry):
    res = 0
    for in in array:
        res+=i
    return res
cal = timer(cal)
cal(range(10)

语法糖@

@timer 
def cal()
    def cal(array):
      res=0
      for i in array:
          res+=i
      return res
 
  cal(range(10))

有参装饰器

user_list=[
    {name:alex,passwd:123},
    {name:linhaifeng,passwd:123},
    {name:wupeiqi,passwd:123},
    {name:yuanhao,passwd:123},
]
current_user={username:None,login:False}
def auth(auth_type=file):
    def auth_deco(func):
        def wrapper(*args,**kwargs):
            if auth_type == file:
                if current_user[username] and current_user[login]:
                    res = func(*args,**kwargs)
                    return res
                username = input(用户名:).strip()
                passwd = input(密码:).strip()
                for index,user_dic in enumerate(user_list):
                    if username == user_dic[name] and passwd ==username[passwd]:
                        current_user[username] =username
                        current_user[login]=True
                        res = func(*args,**kwargs)
                        return res
                        break
                else:
                    print(用户名或者密码错误,重新登录)
            elif auth_type ==ldap:
                print(登录成功)
                res = func(*args,**kwargs)
                return res
        return wrapper
    return auth_deco
@auth(auth_type=ldap)
def index():
    print(欢迎来到主页面)
@auth(auth_type=ldap)
def home():
    print(家目录)
def shopping_car():
    print(购物车页面)
def order():
    print(订单页面)
index()
home()

 

作用域规则 每次执行执行一个函数时,就会创建新的局部命名空间。该命名空间代表一个局部环境,其中包含函数参数的名称和在函数体内赋值的变量名称。解析这些名称 时,解释器首先搜索局部命名空间、如何没有找到匹配的名称,它就会搜索全局命名空间。函数的全局命名空间始终是定义该函数的模块。如果解释器在全局命名空间中也找不到匹配值,最终会检查内置命名空间。如果仍然找不到,就会引发NameError异常 技术分享

python函数下篇装饰器和闭包,外加作用域

标签:方式   action   参数   start   app   空间   name   lis   名称   

原文地址:http://www.cnblogs.com/songcheng/p/7051229.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!