目录:

一、Debug操作

二、函数的装饰器

三、迭代器

四、生成器

一、Debug操作:

程序出问题的时候可以用debug来看一下代码运行轨迹,然后找找问题在哪里

1.先给即将debug的代码打上断点:

 2.打完断点之后右键点击debug:

 3.然后依次点击开始按钮让程序开始一步步运行:

二、函数的装饰器:

定义:装饰器为其他函数添加附加功能,本质上还是一个函数

原则:①不修改被修饰函数的源代码

      ②不修改被修饰函数的调用方式

有这样一个函数:demo()

先导入时间模块,然后函数执行时先睡两秒,在执行打印

 import time
def demo():
time.sleep(2)
print("welcome sir")
demo()

现在想为demo()函数添加一个统计函数运行时间的功能,但是要遵循开放封闭原则

初步思想:

 import time
def demo():
start_time = time.time()
time.sleep(2)
print("welcome sir")
end_time = time.time()
print("运行时间%s" %(end_time-start_time))
demo()

这样就完美解决了,但是,我们要用可持续发展的眼光来看,假如有十万个代码,我们这样一个一个添加,你不加班谁加班?

这个时候我们可以用函数的思维来解决

进步思想:

 import time
def demo():
time.sleep(2)
print("welcome sir")
def timmer(func_name):
def inner():
start_time = time.time()
func_name()
end_time = time.time()
print("运行时间%s" %(end_time-start_time))
return inner
res = timmer(demo)
res()

这样看起来非常Nice,用到了高阶函数,嵌套函数,函数闭包,但是我们违反了开放封闭原则,这个时候把res 改成 demo 就可以了

在这里有一个命令,可以直接略过这个赋值,让代码看起来更美观,执行效率更高

 import time
def timmer(func_name):
def inner():
start_time = time.time()
func_name()
end_time = time.time()
print("运行时间%s" %(end_time-start_time))
return inner
@timmer
def demo():
time.sleep(2)
print("welcome sir")
demo()

ok,代码完成,这其实就是一个函数装饰器,我们来解释一下代码运行顺序

为装饰器加上返回值:

 import time
def timmer(func_name):
def inner():
start_time = time.time()
res = func_name()
end_time = time.time()
print("运行时间%s" %(end_time-start_time))
return res
return inner
@timmer
def demo():
time.sleep(2)
return '函数demo的返回值'
val = demo()
print(val)

有参数的装饰器:

 import time
def timmer(func_name):
def inner(*args,**kwargs):
start_time = time.time()
res = func_name(*args,**kwargs)
end_time = time.time()
print("运行时间%s" %(end_time-start_time))
return res
return inner
@timmer
def demo(name,age):
time.sleep(2)
return '函数demo的返回值,姓名:%s,年龄:%s' %(name,age)
val = demo('zrh',20)
print(val)

图示流程:

三、迭代器: 

可迭代协议:只要包括了"_iter_"方法的数据类型就是可迭代的

 print([1,2,3].__iter__())  #打印结果:<list_iterator object at 0x000002E7F803DE88>

iterable 形容词 可迭代的

 from collections import Iterable  #检测一个对象是否可迭代
print(isinstance('aaa',Iterable))
print(isinstance(123,Iterable))
print(isinstance([1,2,3],Iterable))

迭代器协议:迭代器中有 __next__ 和 __iter__方法 

iterator 名词 迭代器,迭代器 就是实现了能从其中一个一个的取出值来

检测参数是不是个迭代器:

 from collections import Iterator
print(isinstance(lst_iterator,Iterator))
print(isinstance([1,2,3],Iterator))

在python里,目前学过的所有的可以被for循环的基本数据类型都是可迭代的,而不是迭代器。

迭代器包含可迭代对象

可迭代对象转换为迭代器:

可迭代对象._iter_()  这样就变成可一个迭代器

lise_case = [1,2,3].__iter__()

迭代器存在的意义:

1.能够对python中的基本数据类型进行统一的遍历,不需要关心每一个值分别是什么
2.它可以节省内存 —— 惰性运算

for循环的本质:

 lst_iterator = [1,2,3].__iter__()
while True:
try:
print(lst_iterator.__next__())
except StopIteration:
break

只不过for循环之后如果参数是一个可迭代对象,python内部会将可迭代对象转换成迭代器而已。

四、生成器:

Iterator 迭代器

Gerator 生成器

生成器其实就是迭代器,生成器是用户写出来的

 def generator_func():    #生成器函数
print(123)
yield 'aaa'
generate = generator_func()
print(generate)
print(generate.__next__())
# 打印结果:
# <generator object generator_func at 0x0000018F3942E8C8>
#
# aaa

带yield关键字的函数就是生成器函数,包含yield语句的函数可以用来创建生成器对象,这样的函数也称为生成器函数。

yield语句与return语句的作用相似,都是用来从函数中返回值,return语句一旦执行会立刻结束函数的运行

而每次执行到yield语句并返回一个值之后会暂停或挂起后面的代码的执行,下次通过生成器对象的__next__()、for循环或其他方式索要数据时恢复执行

生成器具有惰性求值的特点

生成器运行顺序:

生成器问题注意1:

 def generator_func():    #生成器函数
print(123)
yield 'aaa'
print(456)
yield 'bbb'
ret_1 = generator_func().__next__()
print(ret_1)
ret_2 = generator_func().__next__()
print(ret_2)
# 输出结果:
#
# aaa
#
# aaa
def generator_func(): #生成器函数
print(123)
yield 'aaa'
print(456)
yield 'bbb'
generate_1 = generator_func()
ret_1 = generate_1.__next__()
print(ret_1)
ret_2 = generate_1.__next__()
print(ret_2)
# 输出结果:
#
# aaa
#
# bbb

第6行和第8行相当于创建了两个生成器,第20行创建了一个生成器,21行和23行都用的是第20行创建的生成器,所以输出结果不一样

生成器问题注意2:

for循环完了之后生成器数据就取完了,再继续print数据的话,就会报错,因为没有数据可以读了。

一个函数有两个以上的yield,才算一个必要的生成器,如果只有一个yield,那还不如老老实实的去写return

生成器实例:

需求:写一个实时监控文件输入的内容,并将输入内容返回的函数

 def tail(filename):
f = open(filename,encoding='utf-8')
f.seek(0,2)
while True:
line = f.readline()
if not line:continue
yield line
tail_g = tail('file_1')
for line in tail_g:print(line,end='')

生成器send用法:

1.send和next工作的起止位置是完全相同的
2.send可以把一个值作为信号量传递到函数中去
3.在生成器执行伊始,只能先用next
4.只要用send传递参数的时候,必须在生成器中还有一个未被返回的yield

 def average_func():
total = 0
count = 0
average = 0
while True:
value = yield average
total += value
count += 1
average = total/count
g = average_func()
print(g.__next__())
print(g.send(30))
print(g.send(20))

代码解释:

装饰器生成激活函数装置:

 def wrapper(func):
def inner(*args,**kwargs):
g = func(*args,**kwargs)
g.__next__()
return g
return inner
@wrapper
def average_func():
total = 0
count = 0
average = 0
while True:
value = yield average
total += value
count += 1
average = total/count
g = average_func()
print(g.send(30))

利用函数装饰器写了一个函数激活装置,就不用在18行之前的send前使用 next 了,next 在第4行已经实现了。

python-Debug、函数装饰器的更多相关文章

  1. python基础—函数装饰器

    python基础-函数装饰器 1.什么是装饰器 装饰器本质上是一个python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能. 装饰器的返回值是也是一个函数对象. 装饰器经常用于有切 ...

  2. Decorator——Python初级函数装饰器

    最近想整一整数据分析,在看一本关于数据分析的书中提到了(1)if __name__ == '__main__' (2)列表解析式 (3)装饰器. 先简单描述一下前两点,再详细解说Python初级的函数 ...

  3. python基础-----函数/装饰器

    函数 在Python中,定义一个函数要使用def语句,依次写出函数名.括号.括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回. 函数的优点之一是,可以将代码块与主程 ...

  4. python 复习函数 装饰器

    # 函数 —— 2天 # 函数的定义和调用 # def 函数名(形参): #函数体 #return 返回值 #调用 函数名(实参) # 站在形参的角度上 : 位置参数,*args,默认参数(陷阱),* ...

  5. day11 python之函数装饰器

    一,什么是装饰器? 装饰器本质上就是一个python函数,他可以让其他函数在不需要做任何代码变动的前提下,增加额外的功能,装饰器的返回值也是一个函数对象. 装饰器的应用场景:比如插入日志,性能测试,事 ...

  6. python 匿名函数&装饰器

    匿名函数 关键字lambda表示匿名函数,冒号前面的x表示函数参数匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果. >>> list(map(l ...

  7. python闭包函数&装饰器

    一.函数引用 函数可以被引用 函数可以被赋值给一个变量 def hogwarts(): print("hogwarts") # hogwarts() # 函数调用 print(ho ...

  8. Python之函数装饰器

    在实际中,我们可能需要在不改变函数源代码和调用方式的情况下,为函数添加一些新的附加功能,能够实现这种功能的函数我们将其称之为装饰器.装饰器本质上其实还是是一个函数,用来装饰其它函数,为函数添加一些附加 ...

  9. python 之 函数 装饰器

    5.8 装饰器 1 开放封闭原则 软件一旦上线后,就应该遵循开放封闭原则,即对修改源代码是封闭的,对功能的扩展是开放的 也就是说我们必须找到一种解决方案: 能够在不修改一个功能源代码以及调用方式的前提 ...

  10. Python中函数装饰器及练习

    )])   ,,],)

随机推荐

  1. postgresql从库搭建

    1 复制类型 PostgreSQL支持物理复制(流复制)及逻辑复制2种.通过流复制技术,可以从实例级复制出一个与主库一模一样的实例级的从库.流复制同步方式有同步.异步两种. 另一种复制方式为逻辑复制, ...

  2. 基于Spark的电影推荐系统(电影网站)

    第一部分-电影网站: 软件架构: SpringBoot+Mybatis+JSP 项目描述:主要实现电影网站的展现 和 用户的所有动作的地方 技术选型: 技术 名称 官网 Spring Boot 容器 ...

  3. 编程范式 --- 面向协议编程(Protocol Oriented Programming,简称POP)

    面向协议编程(Protocol Oriented Programming,简称POP) 是Swift的一种编程范式,Apple于2015年WWDC踢出 在Swift的标准库中,能见到大量POP的影子 ...

  4. Spring 梳理-webApplicationContext 与servletContext

    1.WebApplicationContext的研究 ApplicationContext是spring的核心,Context通常解释为上下文环境,用“容器”来表述更容易理解一些,Applicatio ...

  5. Vue2.0+ElementUI实现表格翻页的实例

    参考地址: https://www.cnblogs.com/zhouyifeng/p/7706815.html

  6. java面向对象,数据类型深入

    java程序员面试题day02 1.类和对象有什么区别? java中的类通过class关键字进行定义,代表的是一种抽象的集合,在类中可以定义各种的属性和方法,代表的是每一个类的实例的特定的数据和动作, ...

  7. 【SQL server基础】初步学习存储过程(好学易懂)

    -------------------------------------------------------------------------- ------------------------- ...

  8. 基于elasticsearch的自定义业务告警的设计思路

    A系统与B系统之间有很多接口交互,但是有一段时间接口经常报错,作为开发如果不能第一时间知道问题且及时解决的话就会收到业务投诉,当月绩效凉凉. 如果你也有这种场景,那么你就需要一个及时告警的功能. 实现 ...

  9. .Net Core 商城微服务项目系列(十四):分布式部署携程Apollo构建配置中心

    一.开场白 在系统设计里我们有很多配置希望独立于系统之外,而又能够被系统实时读取.但是在传统的系统设计里,配置信息通常是耦合在系统内的,比如.net里通常会放在App.config或者web.conf ...

  10. php无限级分类实战——评论及回复功能

    经常在各大论坛或新闻板块详情页面下边看到评论功能,当然不单单是直接发表评论内容那么简单,可以对别人的评论进行回复,别人又可以对你的回复再次评论或回复,如此反复,理论上可以说是没有休止,从技术角度分析很 ...