目录:

一、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. 性能测试之 Gatling

    在应用程序上线之前,有多少人做过性能测试? 估计大部分开发者更多地关注功能测试,并且会提供一些单元测试和集成测试的用例.然而,有时候性能漏洞导致的影响比未发现的业务漏洞更严重,因为性能漏洞影响的是整个 ...

  2. 站内搜索(ELK)之开篇

    因工作需要,近期使用ELK搭建单位内部“站内搜索”,目前已将内部OA系统20余个流程的表单.附件的数据索引到elasticsearch中,包括打印复印流程.声像采集流程.远程文件发送.规章制度.内线电 ...

  3. JS 生成唯一值UUID

    md5加密new Date()生成的值可能不是唯一的,另一种生成唯一值的方式: getUID: function() { // 获取唯一值 return 'xxxxxxxx-xxxx-4xxx-yxx ...

  4. 原创电子书《菜鸟程序员成长之路:从技术小白到阿里巴巴Java工程师》

    <菜鸟程序员成长之路:从技术小白到阿里巴巴Java工程师> 国庆节快乐!一年一度长度排第二的假期终于来了. 难得有十一长假,作者也想要休息几天啦. 不管你是选择出门玩,还是在公司加班,在学 ...

  5. mysql高级扩展

    有关网址: MySQL 性能优化神器 Explain 使用分析 MySQL - EXPLAIN详解 1.时间比较 mysql> SELECT something FROM table WHERE ...

  6. Python 命令行参数解析工具 argparse

    为什么需要argparse 开门见山,举一个简易计算器代码的例子,其中sys.argv用来读取脚本执行时后面传入的参数. def calculator(x, y, operation): if &qu ...

  7. Kylin构建Cube过程详解

    1 前言 在使用Kylin的时候,最重要的一步就是创建cube的模型定义,即指定度量和维度以及一些附加信息,然后对cube进行build,当然我们也可以根据原始表中的某一个string字段(这个字段的 ...

  8. php微信支付v3版本签名生成

    前几天需要对接微信支付卡包营销活动需要对接微信新版SDKv3版 签名生成规则,微信的官方文档里面说明的还算可以吧,不过个人觉得不太理想- -.  自己调试的时候调试了半天才找了错误原因. https: ...

  9. 关于人工智能和python

    人工智能的话题在近几年可谓是相当火热,前几天看快本时其中有一个环节就是关于人工智能的,智能家电.智能机器人.智能工具等等,在我的印象里,提到人工智能就会出现 Python,然后我便在网上查找了相关信息 ...

  10. JZOJ10004 列车调度

    [JZOJ100041]列车调度 Description Input Output Sample Input Sample1: 3 1 2 3 Sample2: 9 1 3 2 4 8 6 9 5 7 ...