Python之路Day11

今日大纲
1.昨日内容补充
2.函数名的应用
3.闭包
4.装饰器

1.昨日内容补充
def func1(*args,**kwargs): #聚合 11 22 33 变成(11, 22, 33)#聚合 变成{"name":"david"}
    print(args)        #11, 22, 33)
    print(*args)       #打散args 变成 11 22 33
    print(kwargs)      #打印{"name":"david"}
    print(**kwargs)    #报错,打散是name = "david",但是print函数不接受关键字参数
func1(*[11, 22, 33],**{"name":"david"}) #打散[11,22,33],变成 11 22 33 打散{"name":"david"} 变成 name="david"

典型例题:
def func():
    def func1():
        name ="老男孩"
    def func2():
        nonlocal name
        name = "alex"
    def func3():
        global name
        name = "太白"
    name = "日天"

    func1()
    print(name)  # 1 日天
    func2()
    print(name)  # 2,alex
    func3()
    print(name)  # 3,alex
func()
print(name)  # 4,太白
2.函数名的应用
(1)直接打印函数名得到的是函数的内存地址
def func1():
    print(func1) #<function func1 at 0x00000000021392F0>

func1()
(2)函数名可以赋值运算
def func1():
    print(666)

f1 = func1
f1() #等同于 func1
(3)函数名可以作为函数的参数
def func1(x):
    print(666)
    x()

def func2():
    print(333)

func1(func2)
(4)函数名可以作为容器型数据类型的元素
def func1():
    print(111)

def func2():
    print(222)

def func3():
    print(333)

def func4():
    print(444)

li = [func1,func2,func3,func4]
for i in li:
    i()

dic = {1:func1,2:func2,3:func3,4:func4}
for k in dic:
    dic[k]()
(5)函数名可以当做函数的返回值
def func1():
    print(111)

def func2(x):
    print(666)
    return x
ret = func2(func1)
ret()
(6)第一类对象(first-class object)指
1)可在运行期创建
2)可用作函数参数或返回值
3)可存入变量的实体。
 

3.闭包
定义:内层函数对外层函数非全局变量的引用就是闭包。
如何判断是否是闭包:函数名.__closure__
返回值若为None则不是闭包;
返回值若为cell.....则是闭包
作用:当执行一个函数时,如果解释器判断此函数内部闭包存在,这样
Python就一个机制,闭包的所在的临时名称空间不会随着函数的执行完毕而消失。
def func1():
    name = "david"
    def func2():
        print(name)
    func2()
    print(func2.__closure__)

func1()
执行结果:
david
(<cell at 0x000000000261D828: str object at 0x00000000025F2490>,)

def func1():
    global name
    name = "david"
    def func2():
        print(name)
    func2()
    print(func2.__closure__)

func1()
执行结果:
david
None

def func1(x):
    #x = "老男孩"
    def inner():
        print(x)
    inner()
    print(inner.__closure__)

name = '老男孩'
func1(name)
执行结果:
老男孩
(<cell at 0x00000000021CD828: str object at 0x00000000021ACE70>,)
4.装饰器
def wrapper(f):
    def inner(*args,**kwargs):
        """执行被装饰函数之前的操作"""
        ret = f(*args,**kwargs)
        """执行被装饰函数之后的操作"""
        return ret
    return inner

装饰器功能:在不改变原函数的基础上,为原函数增加一些额外的功能,log,登录注册,等等.
题目:测试函数的效率
第一版本
import time
def func1():
    time.sleep(0.3)
    print("待到阴阳逆乱时,以我魔血染青天!")

def timmer():
    start_time = time.time()
    func1()
    end_time = time.time()
    print("用时%ss"%(end_time-start_time))

timmer()

第二版本
要求:要求可以测试多个函数
import time
def func1():
    time.sleep(0.3)
    print("待到阴阳逆乱时,以我魔血染青天!")

def func2():
    time.sleep(0.4)
    print("天地为棋,众生为子!")

def timmer(f):
    start_time = time.time()
    f()
    end_time = time.time()
    print("用时%ss"%(end_time-start_time))

timmer(func1)
timmer(func2)

第三版本
要求使用原函数执行方式
import time
def func1():
    time.sleep(0.3)
    print("待到阴阳逆乱时,以我魔血染青天!")

def timmer(f):   #func1(f1) 时,执行函数
    start_time = time.time()
    f() #f1 就是要测试的函数的函数名func1
    end_time = time.time()
    print("用时%ss"%(end_time-start_time))

f1 = func1        #将func1 作为要传给timmer 形参f的 实参的位置参数,赋值给f1
func1 = timmer    #定义一个新变量func1(不同于函数名func1),将函数名timmer 赋值给 func1
func1(f1)  #我最终想要的func1(f1)等同于 timmer(func1)

第四版本
初级装饰器
import time
def func1():
    time.sleep(0.3)
    print("待到阴阳逆乱时,以我魔血染青天!")

def timmer(f):   #f = func1
    def inner():
        start_time = time.time()
        f() #f1 就是要测试的函数的函数名func1   # func1() 此时调用函数func1()
        end_time = time.time()
        print("用时%ss"%(end_time-start_time))
    return inner

func1 = timmer(func1) # func1 = inner
func1() #inner()
第五版本
简单装饰器 语法糖
def timmer(f):   #f = func1
    def inner():
        start_time = time.time()
        f() #f1 就是要测试的函数的函数名func1   # func1() 此时调用函数func1()
        end_time = time.time()
        print("用时%ss"%(end_time-start_time))
    return inner

@timmer    #等同于 func1 = timmer(func1)
def func1():
    time.sleep(0.3)
    print("待到阴阳逆乱时,以我魔血染青天!")

func1() #inner()


@timmer  # 等同于 func1 = timmer(func1)
def func2():
    time.sleep(0.4)
    print("天地为棋,众生为子!")

func2() #inner()
第六版本
能够传递参数的装饰器
import time
def timmer(f):   #f = func1
    def inner(*args,**kwargs): #(111,222)
        start_time = time.time()
        f(*args,**kwargs) #f 就是要测试的函数的函数名func1   # func1() 此时调用函数func1() #将(111,222)打碎 111 222
        end_time = time.time()
        print("用时%ss"%(end_time-start_time))
    return inner

@timmer    #等同于 func1 = timmer(func1)
def func1(a,b):
    print(a,b)
    time.sleep(0.3)
    print("待到阴阳逆乱时,以我魔血染青天!")

func1(111,222) #inner(111,222)


@timmer  # 等同于 func2 = timmer(func2)
def func2(a):
    print(a)
    time.sleep(0.4)
    print("天地为棋,众生为子!")

func2(666) #inner(666)

第七版本
带返回值的装饰器
import time
def timmer(f):   #f = func1
    def inner(*args,**kwargs): #(111,222)
        start_time = time.time()
        ret = f(*args,**kwargs) #f 就是要测试的函数的函数名func1   # func1() 此时调用函数func1() #将(111,222)打碎 111 222
        end_time = time.time()
        print("用时%ss"%(end_time-start_time))
        return ret
    return inner

@timmer    #等同于 func1 = timmer(func1)
def func1(a,b):
    print(a,b)
    time.sleep(0.3)
    print("待到阴阳逆乱时,以我魔血染青天!")
    return 666

print(func1(111,222)) #inner(111,222)


@timmer  # 等同于 func2 = timmer(func2)
def func2(a):
    print(a)
    time.sleep(0.4)
    print("天地为棋,众生为子!")
    return 666

print(func2(777)) #inner(666)

例题:
from urllib.request import urlopen

def index():
    url = "http://www.xiaohua100.cn/index.html"
    def get():
        return urlopen(url).read()
    return get

xiaohua = index()
content = xiaohua()

print(content)

 

 

posted on 2018-05-12 17:05  Y易然R  阅读(126)  评论(0)    收藏  举报

导航