Python学习之函数

1. 函数迭代器
yeald生成器,也是迭代器的一种

def frange(start, stop, step):
    x = start
    while x < stop:
        yield x
        x += step

for i in frange(10, 20 ,0.5):
    print(i)

2.闭包
内部函数引用外部函数变量
定义内部函数后,使用return做外部函数返回值时,要返回内部函数的函数名称

def func():
    a = 1
    b = 2
    return a + b

def sum(a):
    def add(b):
        return a+b
    return add

#add 函数名称或函数的引用
#add()函数的调用

num1 = func()
num2 = sum(2)
print(num2(4))
def counter():
    cnt = [0]
    def add_one():
        cnt[0] += 1
        return cnt[0]
    return add_one

num1 = counter()
print(num1())

3. 装饰器
首先定义一个time函数,判断当前函数运行了多少秒

import time

print(time.time())

def i_can_sleep():
    time.sleep(3)

start_time = time.time()
i_can_sleep()
stop_time = time.time()

print("函数运行了 %s 秒" %(stop_time-start_time))

运行结果为:

1631667848.5058906
函数运行了 3.0053110122680664 秒

Process finished with exit code 0

一般函数的使用,但如果有大量的i_can_sleep()函数时,就要编写大量的这样的函数吗?当然不是,我们需要将大量重复性的只做一次,此时就可以使用装饰器来实现
装饰器怎么写了?在定义函数上面写一个@符号,后面写上要装饰i_can_sleep()函数的名称

#@timer叫做语法行,timer叫做装饰器中的装饰函数,i_can_sleep叫做被装饰函数
@timer
def i_can_sleep():
    time.sleep(3)

把装饰函数和被装饰函数写好之后,就可以把之前额外的功能封装到装饰函数里面timer
将函数改写为

import time

#print(time.time())
def timer(func):
    def warpper():
        start_time = time.time()
        func()
        stop_time = time.time()
        print("函数运行了 %s 秒" % (stop_time - start_time))
    return warpper

#@timer叫做语法行,timer叫做装饰器中的装饰函数,i_can_sleep叫做被装饰函数
@timer
def i_can_sleep():
    time.sleep(3)

#start_time = time.time()
i_can_sleep()
#stop_time = time.time()

#print("函数运行了 %s 秒" %(stop_time-start_time))

运行结果:

函数运行了 3.0034825801849365 秒

Process finished with exit code 0

发现用了装饰器和不用装饰器时的结果是一样的,区别在哪了?
会发现用了装饰器后,可以直接去使用i_can_sleep()函数,不用再写start_time和stop_time了,那么用了装饰器后的执行过程是怎么样的?
当调用i_can_sleep()函数时,发现上面有一个@timer装饰器,而@timer是来修饰i_can_sleep()函数的,所以python就是调用timer(i_can_sleep())函数,然后把i_can_sleep()函数传递到timer()函数中,timer()函数中接收一个func的变量,然后传递给内部函数,传递进来之后,内部的wapper函数定义了start_time和stop_time,然后把func()定义到中间,所以运行的时候,先执行start_time、func、stop_time、进行计算之后在进行输出,最后返回的时候返回内部函数的函数名。

可以看到装饰器和闭包是非常类似的,但是他们之间有什么区别了?
闭包穿进来的是变量,内部函数引用的也是变量
装饰器传进来的是一个函数,内部引用的也是一个函数

回到外部,timer(i_can_sleep)引用我们的i_can_sleep,引用完了之后会传递给一个指定的变量:num = timer(i_can_sleep),然后再用变量使用函数的方式num()

num = timer(i_can_sleep)
num()

但是这样的写法不是很简便,因此就演变成了@timer装饰器的写法,而下面直接运行的时候,不用写那么复杂的闭包的调用过程了,就是使用i_can_sleep(),就自动去找@timer装饰器

装饰器的使用
不带参数的装饰写法

def wai(func):
    def nei():
        start
        func()
        stop
        return '内部函数返回值'
    return '内部函数的名称'

带参数时要把参数传递进去

def tips(func):
    def nei(a,b):
        print('start')
        func(a,b)
        print('stop')
    return nei

@tips
def add(a,b):
    print(a+b)

针对不同函数的装饰器会不一样吗?就是给装饰器后面带上相应的参数
使用装饰器的好处:
1.调用函数时不用重复的编写修饰代码,可以放到装饰器里面
2.如果装饰器的代码需要复用时,可以用@装饰器的名字就可以

def new_tips(argv):
    def tips(func):
        def nei(a,b):
            print('start %s %s' %(argv,func.__name__))
            func(a,b)
            print('stop')
        return nei
    return tips

@new_tips('add_module')
def add(a,b):
    print(a+b)

@new_tips('sub_module')
def sub(a,b):
    print(a-b)

print(add(4,5))
print(sub(7,3))def tips(func):
    def nei(a,b):
        print('start')
        func(a,b)
        print('stop')
    return nei

运行结果:

start add_module add
9
stop
None
start sub_module sub
4
stop
None

4.自定义上下文管理器
使用with来实现上下文管理器

with open('name.txt') as f:
	for line in f:
		print(line)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咸宁七s

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值