文章目录

  • 1.列表生成式
  • 2.匿名函数
  • 3.装饰器
  • 4.生成器
  • 5.迭代器
  • 6.内置函数
  • 7.json & pickle 序列化与反序列化

1.列表生成式

可通过特定语句便捷生成列表

list1 = [ i * 2 for i in range(10)]
print(list1) #[0, 2, 4, 6, 8, 10, 12, 14, 16, 18][x * x for x in range(1, 11) if x % 2 == 0]
#[4, 16, 36, 64, 100]def func(i):print('processing....')return i + 1list2 = [func(i) for i in range(10) ]

还可以使用两层循环,生成全排列:

[m + n for m in 'ABC' for n in 'XYZ']
#['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']

2.匿名函数

  匿名函数就是不需要显示指定的函数,用完即会释放内存空间,且只能执行简单的操作,如循环语句等就不能执行。

calc = lambda n:print(n)
calc(5) #5
#or
(lambda n:print(n))(5)  #5

3.装饰器

  装饰器说白了就是用于装饰其他的函数,如添加功能。
强调装饰器的原则:
  1 )不修改被装饰对象的源代码
  2 )不修改被装饰对象的调用方式
  装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能
装饰器满足开闭原则,即:对修改关闭,对拓展开放

装饰器可传参也可不传参:

def timer(func):def warpper(*args,**kwargs):   #通用,可传参也可不传参start_time = time.time()func(*args,**kwargs)stop_time = time.time()print('the func run time is %s' %(stop_time - start_time))return warpper@timer # 相当于 test2 = timer(test2)
def test2(name,age):print('in the test2',name,age)test2('yleave',22)@timer # 相当于 time1 = timer(time1)
def time1():time.sleep(3)print('in the test1')time1()

装饰器中可使用函数嵌套来调整参数传递:

user,psd = 'yleave','123456'
def auth(auth_type):print('auth func:',auth_type)def outer_wrapper(func):def wrapper(*args,**kwargs):print('wrapper func args:',*args,**kwargs)if(auth_type == 'local'):username = input('Username:').strip()password = input('Password:').strip()if username == user and password == psd:print('\033[32:1mUser has passed authentication\033[0m')res = func(*args,**kwargs)print('----after authentication')return reselse:exit('\033[31:1mInvalid username or password\033[0m')elif auth_type == 'ldap':print('-------ladp-----')return wrapperreturn outer_wrapperdef index():print('Welcome to index page!')@auth(auth_type = 'local') #加了个括号,因此开始执行 outer_wrapper(home) ,最终 home = wrapper
def home():print('Welcome to home page!')return 'from home'@auth(auth_type = 'ldap')
def bbs():print('Invalid username or password!')index()
print(home())
bbs()'''
author_type: local
author_type: ldap
Welcome to index page!
warrper func args: ()
warrper func args: {}
Username: yleave
Password: 123456
User has passed authentication
Welcome to home page!
----after authentication
from home
warrper func args: ()
warrper func args: {}
-------ladp-------
'''

不过,由于函数也是对象,有一些属性,比如 __name__ 属性,在使用装饰器后,它们的 name 已经从 homebbs 变为 wrapper 了:

因为返回的那个 wrapper() 函数名字就是 wrapper,所以,需要把原始函数的 __name__ 等属性复制到 wrapper() 函数中,否则,有些依赖函数签名的代码执行就会出错。

不需要编写 wrapper.__name__ = func.__name__ 这样的代码, Python 内置的 functools.wraps 就是干这个事的,所以,一个完整的装饰器的写法如下:

def auth(author_type):print('author_type:',author_type)def outer_wrapper(func):@functools.wraps(func)def wrapper(*args, **kwargs):print('warrper func args:',args)print('warrper func args:',kwargs)if author_type == 'local':username = input('Username:').strip()password = input('Password:').strip()if username == user and password == pwd:print('\033[32:1mUser has passed authentication\033[0m')res = func(*args,**kwargs)print('----after authentication')return reselse:exit('\033[31:1mInvalid username or password\033[0m')elif author_type == 'ldap':print('-------ladp-------')return wrapperreturn outer_wrapper

装饰器最多可叠加六个:

@deco1
@deco2
@deco3
def foo():passfoo=deco1(deco2(deco3(foo)))
def outter1(func1): #func1=wrapper2的内存地址print('加载了outter1')def wrapper1(*args,**kwargs):print('执行了wrapper1')res1=func1(*args,**kwargs)return res1return wrapper1def outter2(func2): #func2=wrapper3的内存地址print('加载了outter2')def wrapper2(*args,**kwargs):print('执行了wrapper2')res2=func2(*args,**kwargs)return res2return wrapper2def outter3(func3): # func3=最原始的那个index的内存地址print('加载了outter3')def wrapper3(*args,**kwargs):print('执行了wrapper3')res3=func3(*args,**kwargs)return res3return wrapper3@outter1 # outter1(wrapper2的内存地址)======>index=wrapper1的内存地址
@outter2 # outter2(wrapper3的内存地址)======>wrapper2的内存地址
@outter3 # outter3(最原始的那个index的内存地址)===>wrapper3的内存地址
def index():print('from index')print('======================================================')
index()'''输出结果
加载了outter3
加载了outter2
加载了outter1
======================================================
执行了wrapper1
执行了wrapper2
执行了wrapper3
from index
'''

4.生成器

生成器:generator,实现了一种一边循环一边计算的机制,从而在数据量很大时节省大量内存空间。
生成器的一种创建方法是:

#与列表生成式相似,将中括号改为小括号
generator1 = ( i * 2 for i in range(10))
print(generator1) #<generator object <genexpr> at 0x057E52D0>

生成器的另一种创建方式是使用 field 关键字:

def fib(max):n,a,b = 0,0,1while n < max:#print(b)yield ba,b = b,a + bn += 1return 'done'   #当该函数变成生成器时,此处打印异常信息'''
a,b = b,a + b
相当于
t = (b,a + b)
a = t[0]
b = t[1]
'''
print(fib(10))  #<generator object fib at 0x051852D0>

访问生成器中的元素可用 next 方法或使用 for 循环:

f = fib(10)
print(f.__next__())
#or
print(next(f))print('----start loop----')
for i in f:print(i)g = fib(6)
while True:try:x = next(g)print('g:',x)except StopIteration as e:print('Generator return value:',e.value)break;#当超出生成器 fib 可获取的数时,会返回 fib 中的 done,用 for 循环不会报这种错

  generator 的执行顺序是在每次调用next()的时候执行,遇到 yield 语句返回,再次执行时从上次返回的yield语句处继续执行。

使用 generator 还可在单线程情况下实现并发运算的效果:

def consumer(name):print("%s 准备吃包子啦!" %name)while True:baozi = yieldprint("包子[%s]来了,被[%s]吃了!" %(baozi,name))# c = consumer('yleave')
# c.__next__()
#
# b1 = '韭菜馅'
# c.send(b1) #将 b1 传到生成器中 并成为当前 yield 表达式的结果def producer(name):c = consumer('A')c2 = consumer('B')c.__next__()c2.__next__()print("%s开始准备做包子啦!"%name)for i in range(10):time.sleep(1)print("做了2个包子!")c.send(i)c2.send(i)producer("yle")'''运行效果
A 准备吃包子啦!
B 准备吃包子啦!
yle开始准备做包子啦!
做了2个包子!
包子[0]来了,被[A]吃了!
包子[0]来了,被[B]吃了!
做了2个包子!
包子[1]来了,被[A]吃了!
包子[1]来了,被[B]吃了!
做了2个包子!
包子[2]来了,被[A]吃了!
包子[2]来了,被[B]吃了!
'''

5.迭代器

我们已经知道,可以直接作用于for循环的数据类型有以下几种:

  一类是集合数据类型,如list、tuple、dict、set、str等;

  一类是generator,包括生成器和带yield的generator function。

  这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。
  可以使用isinstance()判断一个对象是否是Iterable对象:

from collections import Iterableprint(isinstance([],Iterable))  #Trueprint(isinstance({},Iterable))  #Trueprint(isinstance('abc',Iterable))  #Trueprint(isinstance((x for x in range(10)),Iterable))  #Trueprint(isinstance(100,Iterable))  #False

  而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。

可以使用isinstance()判断一个对象是否是Iterator对象:

from collections import Iteratorprint(isinstance([],Iterator))  #Falseprint(isinstance({},Iterator))  #Falseprint(isinstance('abc',Iterator))  #Falseprint(isinstance((x for x in range(10)),Iterator))  #True

生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。

把list、dict、str等Iterable变成Iterator可以使用iter()函数:

print(isinstance(iter([]),Iterator))  #Trueprint(isinstance(iter({}),Iterator))  #Trueprint(isinstance(iter('abc'),Iterator))  #True

  Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。
  Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。

小结
  凡是可作用于for循环的对象都是Iterable类型;

  凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;

  集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

  Python的for循环本质上就是通过不断调用next()函数实现的,例如:

for x in [1, 2, 3, 4, 5]:pass

实际上完全等价于:

# 首先获得Iterator对象:
it = iter([1, 2, 3, 4, 5])
# 循环:
while True:try:# 获得下一个值:x = next(it)except StopIteration:# 遇到StopIteration就退出循环break

6.内置函数


内置参数详解 https://docs.python.org/3/library/functions.html?highlight=built#ascii

一些内置函数:

'''若可迭代的对象中的所有元素都为真则返回真'''
print(all([1,2,-3]))  #True'''若可迭代的对象中的任意一个元素为真则返回真,空返回False'''
print(any([0,0,1])) #True'''10 进制转 2 进制'''
print(bin(15))  #0b1111'''判断真假'''
print(bool(0))  #False'''字符串是不能被修改的,该方法将字符串转换成二进制格式再进行修改'''
b = bytearray('abcde',encoding='utf-8')
print(b[0])  #97
b[0] = 98
print(b)  #bytearray(b'bbcde')'''判断是否可调用'''
def sayhi():pass
print(callable(sayhi))  #True'''将输入的 ascii 码转换成 字符'''
print(chr(97))  #a'''将输入的字符转换为 ascii 码'''
print(ord('a'))  #97'''查看一个对象可使用的方法'''
str = 'abc'
print(dir(str))'''返回两个数之间的除数和余数'''
print(divmod(5,2))  #(2, 1)'''执行一段代码,返回值为 None'''
code = '''
for i in range(3):print(i)
'''
print(exec(code)) #0 1 2 None'''将给的数据执行特定操作后保存,有点像列表生成式'''
res1 = map(lambda n:n * 2,range(3))
for i in res1:print(i)    #0 2 4'''过滤函数,从给的数据中过滤满足条件的元素'''
#res = filter(lambda n:n > 5,range(10))
res = filter(lambda n:n > 5,map(lambda n:n*2,range(5)))
for i in res:print(i)    #6 8'''按表达式进行累计计算'''
import functools
res = functools.reduce(lambda x,y:x+y,range(4))
print(res)  #6  =  1 + 2 + 3
res1 = functools.reduce(lambda x,y:x*y,range(1,4))
print(res1)  #6  =  1 * 2 * 3'''将 set 变得不可修改,就如元组一样'''
frozenset([1,24,2,1,3,44,2])'''以字典形式返回当前程序中所有的全局变量名与变量值'''
print(globals())'''返回对象的哈希值,哈希值是整数'''
print(hash('yle'))  '''将10进制转为16进制'''
print(hex(15))  #0xf'''将10进制转为8进制'''
print(oct(9))   #0o11'''计算幂'''
print(pow(3,2)) #9'''四舍五入,第二个参数设置保留小数点后几位'''
print(round(1.33678,2)) #1.34'''排序函数,对于字典默认按 key 排序'''
a = {'a':33,'f':21,'d':2,'b':4,'c':5}
print(sorted(a.items()))
#[('a', 33), ('b', 4), ('c', 5), ('d', 2), ('f', 21)]
print(sorted(a.values()))   #[2, 4, 5, 21, 33]
print(sorted(a.items(),key=lambda x:x[1]))
#[('d', 2), ('b', 4), ('c', 5), ('f', 21), ('a', 33)]'''将两组数据拼接起来,若个数不对应,则按顺序来'''
a = [1,2,3,4]
b = ['a','b','c','d']
for i in zip(a,b):print(i)    #(1, 'a') (2, 'b') (3, 'c') (4, 'd')'''模块调用'''
import decorator
or
__import__('decorator')

7.json & pickle 序列化与反序列化

什么是序列化?

  我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。

为什么要序列化?

1:持久保存状态

  需知一个软件/程序的执行就在处理一系列状态的变化,在编程语言中,'状态’会以各种各样有结构的数据类型(也可简单的理解为变量)的形式被保存在内存中。

  内存是无法永久保存数据的,当程序运行了一段时间,我们断电或者重启程序,内存中关于这个程序的之前一段时间的数据(有结构)都被清空了。

  在断电或重启程序之前将程序当前内存中所有的数据都保存下来(保存到文件中),以便于下次程序执行能够从文件中载入之前的数据,然后继续执行,这就是序列化。

  具体的来说,你玩使命召唤闯到了第13关,你保存游戏状态,关机走人,下次再玩,还能从上次的位置开始继续闯关。或如,虚拟机状态的挂起等。

2:跨平台数据交互

  序列化之后,不仅可以把序列化后的内容写入磁盘,还可以通过网络传输到别的机器上,如果收发的双方约定好实用一种序列化的格式,那么便打破了平台/语言差异化带来的限制,实现了跨平台数据交互。

反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。

用于序列化的两个模块:
  json,用于字符串 和 python数据类型间进行转换
  pickle,用于python特有的类型 和 python的数据类型间进行转换

Json模块提供了四个功能:dumps、dump、loads、load
pickle模块提供了四个功能:dumps、dump、loads、load

序列化:

import json
import pickledef sayhi(name):print('hello',name)info = {'name':'yleave','age':22,'func':sayhi#json 只能转换简单的数据,内存地址这种不能序列化#pickle 用法与 json 相同,但能够转换函数,不过只能用于 Python
}'''json 序列化
with open('test.txt','w') as f:f.write(json.dumps(info))
''''''pickel 序列化'''
with open('test1.txt','wb') as f:   #pickle 转换为 字节流f.write(pickle.dumps(info))# or  pickle.dump(info,f)  与上句效果一样

反序列化:

import json
import pickledef sayhi(name):print('hello in pickle',name)'''json 反序列化
with open('test.txt','r') as f:#data = eval(f.read()) eval 将字符串转换为字典data = json.loads(f.read())print(data['age'])
'''
'''pickle 反序列化'''
with open('test1.txt','rb') as f:data = pickle.loads(f.read())# or data = pickle.load(f) 与上句效果相同print(data)data['func']('yleave')  #调用函数

  Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关系。

day4 匿名函数、装饰器、生成器、迭代器、内置函数、 json 与 pickle 模块相关推荐

  1. python函数装饰器有什么用_Python @函数装饰器及用法(超级详细)

    前面介绍的 @staticmethod 和 @classmethod 的本质就是函数装饰器,其中 staticmethod 和 classmethod 都是 Python 内置的函数. 使用 @ 符号 ...

  2. python的shutil模块是内置的_Python之shutil模块11个常用函数详解,python内置函数是什么...

    Python之shutil模块11个常用函数详解,python内置函数是什么 shutil 是 Python 中的高级文件操作模块,与os模块形成互补的关系,os主要提供了文件或文件夹的新建.删除.查 ...

  3. Python基础day4 函数对象、生成器 、装饰器、迭代器、闭包函数

    一.函数对象 正确理解 Python函数,能够帮助我们更好地理解 Python 装饰器.匿名函数(lambda).函数式编程等高阶技术. 函数(Function)作为程序语言中不可或缺的一部分,太稀松 ...

  4. python学习笔记(装饰器、迭代器生成器、内置函数、软件目录开发规范)

    装饰器 定义:本质是函数,(功能:装饰其他函数):就是为其他函数添加附加功能 模拟场景一,在现有的函数中增加某个功能.现有的做法是定义新函数,并且加入函数中.需要修改源代码. def logger() ...

  5. Python装饰器、生成器、内置函数、Json-Day05

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

  6. 函数 装饰器 生成器 面向过程编程

    """# 齐天大圣孙悟空身如玄铁 火眼金睛 长生不老还有七十二变定义函数与调用函数的基本形式 一 ,函数定义的三种形式 1.1 无参函数def foo():print(' ...

  7. python 装饰器 生成器 迭代器和闭包

    1.1装饰器 a.装饰器本质上是python函数或类,它可以让其他函数或类在不需要做任何代码修改的前提下增加额外功能, 装饰器的返回值也是一个函数/类对象 b.常用的需求场景 插入日志,性能测试, 权 ...

  8. 轩小陌的Python笔记-day13 匿名函数、生成器、内置函数、推导式

    day13 内置函数和推导式 今日概要: 匿名函数 生成器 内置函数 附加:推导式,属于数据类型的知识,内部的高级的用法会涉及到[生成器]和[函数]的内容. 1. 匿名函数 传统的函数的定义包括了:函 ...

  9. python-迭代器、生成器、内置函数及面向过程编程

    一.迭代器 迭代器是迭代取值的工具,迭代是一个重复的过程,每一次重复都是基于上一次的结果而来的. 为什么要用迭代器呢? 1.可以不依赖索引取值 2.同一时刻在内存中只有一个值,不会过多的占用内存 如何 ...

  10. format函数python生成列表_python 全栈开发,Day14(列表推导式,生成器表达式,内置函数)...

    一.列表生成式 生成1-100的列表 li = [] for i in range(1,101): li.append(i) print(li) 执行输出: [1,2,3...] 生成python1期 ...

最新文章

  1. 编译型语言和解释型语言(转载)
  2. DM368启动串口打印分析
  3. jquery/css需要记录的小知识(持续补充)
  4. powerdesigner怎么导出pdf_各种科研绘图软件中的矢量图导出技巧
  5. 电脑小常识:电脑键盘失灵怎么办?
  6. 基于NIOS II的液晶显示设计——自定义图形库
  7. SpringMVC介绍之约定优于配置
  8. Netty实战九之单元测试
  9. eclipse 安装svn插件(Subclipse)
  10. ubuntu 12.04 nfs-server/client安装配置
  11. apt-get 操作过程中提示无法解析域名“cn.archive.ubuntu.com” 的解决
  12. 开启Golang编程第一章
  13. php 和 java_Java和php怎么选择??
  14. 重庆计算机c语言二级成绩查询,历届重庆市计算机C语言二级考试试题及答案.pdf...
  15. 卡盟主站搭建_搭建卡盟主站下载|搭建卡盟主站教程 (附带源码)百度云_ - 极光下载站...
  16. 这五款简单又实用自媒体排版工具,你不来试试?
  17. 几种非接触涂层测厚方法原理对比
  18. 大神爆料:红米K30S至尊纪念版和红米10XPro哪个好-哪个更值得入手-参数对比
  19. 机器人系统的基本概念及外部模型参数详解
  20. Codeforces Round #789 (Div. 1) B. Tokitsukaze and Meeting

热门文章

  1. 你见过最垃圾的代码长什么样?(来长长见识)
  2. 互联网大厂有哪些分库分表的思路和技巧?
  3. 彻底取代Redis+数据库架构,京东618稳了!
  4. 我猜你没听过UI自动化技术?
  5. 《大型网站技术架构》《K8S进阶实战》等书籍!送45本!读完工资多个0!
  6. 扒一扒 JVM 的垃圾回收机制,拿大厂offer少不了它!
  7. 程序员的35个坏习惯,你有几条?
  8. 揭秘大型网站架构进化之路
  9. scrum敏捷开发工具实践分享
  10. 非抢占式优先算法例题_三维点云的经典算法与前沿技术有哪些?