生成器

迭代器

装饰器

模块

 

来个需求,一个列表中所有元素都+1

1.最容易想到的方法 for循环,找列表索引,对应每个值+1

list_old = [1,2,3,4,5,6,7,8,9]
for index,i in enumerate(list_old):
list_old[index]+=1
print(list_old)

2.用上节课讲的匿名函数试试,也可以

a = map(lambda x:x+1,list_old)
for i in a:
print(i)

3.列表生成

a = [i+1 for i in list_old]
print(a)
a = [i*2 if i > 5 else i for i in list_old]
print(a)

生成器

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

生成器就是一边循环一边计算的机制,不必创建完整的list,从而节省大量的空间。

要创建一个生成器,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个生成器:

生成器和列表生成的区别就是一个是(),另一个是[]

a = (x*x for x in range(10))
print(next(a))
print(a.__next__())

斐波那契数列

def field(num):
count = 0
a,b = 0,1
while count < num:
tmp = a
a = b
b = a+tmp #a,b = b, a+b
count += 1
yield a  #加上yield,就是生成器了
     print('hehe')
f = field(10000)
print(f.__next__())
print(f.__next__())
yield a  返回a,同时挂起函数,a返回给了通过__next__()调用当前函数,这代表通过yield实现了函数的中断,并且保存了函数的中间执行状态。
生成器和函数的执行顺序是不一样的,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
像上面的例子加上断点后第一次next(),执行到yield a,第二次next(),返回到yield a处继续往下执行print('hehe'),继续while循环,一直执行到yield a。
 
通过yield在单线程情况下模拟并发情况
import time
def consumer(name):
print("%s 准备吃包子啦!" %name)
while True:
baozi = yield print("包子[%s]来了,被[%s]吃了!" %(baozi,name)) def producer(name):
c = consumer('A')
c2 = consumer('B')
c.__next__()
c2.__next__()
print("老子开始准备做包子啦!")
for i in range(10):
time.sleep(1)
print("做了2个包子!")
c.send(i)
c2.send(i) producer("alex")

send(i)相当于__next__(),并且可以传递数据给yield

迭代器

可以作用于for循环的数据类型有以下几种:

一类是集合数据类型,如listtupledictsetstr等;

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

这些可以直接作用于for循环的对象统称为可迭代对象:Iterable

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

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

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

生成器都是Iterator对象,但listdictstr虽然是Iterable,却不是Iterator

listdictstrIterable变成Iterator可以使用iter()函数

总结:

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

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

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

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

2.装饰器

有如下版块,现在需要每个版块都加上认证功能

def home():
print("---首页----") def america():
print("----欧美专区----") def japan():
print("----日韩专区----") def henan():
print("----河南专区----")

take it easy,在每个版块加上调用login()

user_status = False #用户登录了就把这个改成True

def login():
_username = "alex" #假装这是DB里存的用户信息
_password = "abc!23" #假装这是DB里存的用户信息
global user_status if user_status == False:
username = input("user:")
password = input("pasword:") if username == _username and password == _password:
print("welcome login....")
user_status = True
else:
print("wrong username or password!")
else:
print("用户已登录,验证通过...") def home():
print("---首页----") def america():
login() #执行前加上验证
print("----欧美专区----") def japan():
print("----日韩专区----") def henan():
login() #执行前加上验证
print("----河南专区----") home()
america()
henan()

虽然实现了功能,但是违反了软件开发的原则,已实现的功能代码块封闭原则

用高阶函数试试,把一个函数当做参数传给另一个函数

user_status = False #用户登录了就把这个改成True

def login(func): #把要执行的模块从这里传进来
_username = "alex" #假装这是DB里存的用户信息
_password = "abc!23" #假装这是DB里存的用户信息
global user_status if user_status == False:
username = input("user:")
password = input("pasword:") if username == _username and password == _password:
print("welcome login....")
user_status = True
else:
print("wrong username or password!") if user_status == True:
func() # 看这里看这里,只要验证通过了,就调用相应功能 def home():
print("---首页----") def america():
#login() #执行前加上验证
print("----欧美专区----") def japan():
print("----日韩专区----") def henan():
#login() #执行前加上验证
print("----河南专区----") home()
login(america) #需要验证就调用 login,把需要验证的功能 当做一个参数传给login

哦也,实现功能了,也没有改变原版块代码,然而改变了函数的调用方式。

装饰器(高阶函数加嵌套函数)

user_status = False
def login(func):
def inner():
_username = 'alex'
_password = ''
global user_status
if not user_status:
username = input('user:')
password = input('password:')
if username == _username and password == _password:
print('welcome')
user_status = True
else:
print('wrong password or username')
else:
print('用户已经登录')
if user_status == True:
func()
return inner def home():
print("---首页----") def america():
print("----欧美专区----") def japan():
print("----日韩专区----") def henan():
print("----河南专区----") america = login(america)#这行可以用@login替代,在每个需要加的函数前加@login
america()
user_status = False
def login(func):
def inner(*args,**kwargs):
_username = 'alex'
_password = 'abc!23'
global user_status if user_status == False:
username = input('user:')
password = input('password:') if username == _username and password == _password:
print('welcome login...')
user_status = True
else:
print('wrong username or password') if user_status == True:
func(*args,**kwargs)
return inner def home():
print('-----首页------')
@login
def america(style):
print(style)
print('-----欧美专区-----') def japan():
print('-----日韩专区-----') def henan():
print('-----河南专区-----') america('3p')

调用时加上参数,执行时,从上往下,当遇到@login时,america = login(america),实际login返回了inner的内存地址,此时america = inner,继续往下,再次遇到america('3p')时,实际调用inner,把3p参数传给inner,inner('3p'),用户名密码正确后调用america('3p')。

#_*_coding:utf-8_*_

user_status = False #用户登录了就把这个改成True

def login(auth_type): #把要执行的模块从这里传进来
def auth(func):
def inner(*args,**kwargs):#再定义一层函数
if auth_type == "qq":
_username = "alex" #假装这是DB里存的用户信息
_password = "abc!23" #假装这是DB里存的用户信息
global user_status if user_status == False:
username = input("user:")
password = input("pasword:") if username == _username and password == _password:
print("welcome login....")
user_status = True
else:
print("wrong username or password!") if user_status == True:
return func(*args,**kwargs) # 看这里看这里,只要验证通过了,就调用相应功能
else:
print("only support qq ")
return inner #用户调用login时,只会返回inner的内存地址,下次再调用时加上()才会执行inner函数 return auth def home():
print("---首页----") @login('qq')
def america():
#login() #执行前加上验证
print("----欧美专区----") def japan():
print("----日韩专区----") @login('weibo')
def henan(style):
'''
:param style: 喜欢看什么类型的,就传进来
:return:
'''
#login() #执行前加上验证
print("----河南专区----") home()
# america = login(america) #你在这里相当于把america这个函数替换了
#henan = login(henan) # #那用户调用时依然写
america() # henan("3p")

os

提供对操作系统进行调用的接口

os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd
os.curdir 返回当前目录: ('.')
os.pardir 获取当前目录的父目录字符串名:('..')
os.makedirs('dirname1/dirname2') 可生成多层递归目录
os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove() 删除一个文件
os.rename("oldname","newname") 重命名文件/目录
os.stat('path/filename') 获取文件/目录信息
os.sep 输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
os.linesep 输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
os.pathsep 输出用于分割文件路径的字符串
os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system("bash command") 运行shell命令,直接显示
os.environ 获取系统环境变量
os.path.abspath(path) 返回path规范化的绝对路径
os.path.split(path) 将path分割成目录和文件名二元组返回
os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path) 如果path是绝对路径,返回True
os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False
os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间

sys

sys.argv           命令行参数List,第一个元素是程序本身路径
sys.exit(n) 退出程序,正常退出时exit(0)
sys.version 获取Python解释程序的版本信息
sys.maxint 最大的Int值
sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform 返回操作系统平台名称
sys.stdout.write('please:')
val = sys.stdin.readline()[:-1]

__file__相对路径

os.path.abspath(__file__)相对路径变成绝对路径

import sys
import os
BaseDir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BaseDir)#路径加到path中

在python2中,如果目录里没有__init__,那只是一个目录,不能导入,有__init__,那这个目录就变成了‘包’

序列化:把一个内存对象转换成字符串形式

反序列化:把一个字符串转成对应的内存对象

作用:持久化内存对象

序列化:json.dump json.dumps

反序列化:json.loads json.load

json:用于字符串 和 python数据类型间进行转换

import json
data = {
'name':'alex',
'age': 22,
'sex':'m'
}
f = open('data.txt','w',encoding='utf-8')
#f.write(json.dumps(data))
json.dump(data,f)

dump不需要f.write()

import json

f = open("data.txt",encoding="utf-8")

# data = json.loads(f.read())
data = json.load(f)
print(data["age"])

load不需要f.read()

pickle:用于python特有的类型 和 python的数据类型间进行转换

用pickle时打开文件用wb和rb模式,dump之后要记得f.close()

json.dump(data,f) = f.wirte(json.dumps(data))
data=json.load(f) = data=json.loads(f.read())

os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname")  改变当前脚本工作目录;相当于shell下cd
os.curdir  返回当前目录: ('.')
os.pardir  获取当前目录的父目录字符串名:('..')
os.makedirs('dirname1/dirname2')    可生成多层递归目录
os.removedirs('dirname1')    若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname')    生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname')    删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname')    列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove()  删除一个文件
os.rename("oldname","newname")  重命名文件/目录
os.stat('path/filename')  获取文件/目录信息
os.sep    输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
os.linesep    输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
os.pathsep    输出用于分割文件路径的字符串
os.name    输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system("bash command")  运行shell命令,直接显示
os.environ  获取系统环境变量
os.path.abspath(path)  返回path规范化的绝对路径
os.path.split(path)  将path分割成目录和文件名二元组返回
os.path.dirname(path)  返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.basename(path)  返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exists(path)  如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path)  如果path是绝对路径,返回True
os.path.isfile(path)  如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path)  如果path是一个存在的目录,则返回True。否则返回False
os.path.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path)  返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path)  返回path所指向的文件或者目录的最后修改时间

Day5-python基础之函数(二)的更多相关文章

  1. Python基础之函数二

    函数的嵌套 通过名字就能理解,函数里是还可以套着函数用的.这么牛,下面就来看看几段代码,看看是怎么回事.注意:函数一定是先定义后使用. x=1234 def f1(): #定义一个主函数 x = 1 ...

  2. python基础(12):函数(二)

    1. 函数参数 之前我们说过了传参,如果我们需要给⼀个函数传参,⽽参数⼜是不确定的,或者我给⼀个函数传很多参数,我的形参就要写很多,很⿇烦,怎么办呢,我们可以考虑使⽤动态参数. 形参的第三种: 动态参 ...

  3. Python 基础 面向对象之二 三大特性

    Python 基础 面向对象之二 三大特性 上一篇主要介绍了Python中,面向对象的类和对象的定义及实例的简单应用,本篇继续接着上篇来谈,在这一篇中我们重点要谈及的内容有:Python 类的成员.成 ...

  4. python基础篇(二)

    PYTHON基础篇(二) if:else,缩进 A:if的基础格式和缩进 B:循环判断 C:range()函数和len()函数 D:break,contiue和pass语句 for,while循环 函 ...

  5. python基础之函数详解

    Python基础之函数详解 目录 Python基础之函数详解 一.函数的定义 二.函数的调用 三.函数返回值 四.函数的参数 4.1 位置参数 4.2 关键字参数 实参:位置实参和关键字参数的混合使用 ...

  6. python基础——匿名函数

    python基础——匿名函数 当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便.  在Python中,对匿名函数提供了有限支持.还是以map()函数为例,计算f(x)=x2时 ...

  7. python基础——返回函数

    python基础——返回函数 函数作为返回值 高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回.  我们来实现一个可变参数的求和.通常情况下,求和的函数是这样定义的: def calc_ ...

  8. python基础——sorted()函数

    python基础——sorted()函数 排序算法 排序也是在程序中经常用到的算法.无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小.如果是数字,我们可以直接比较,但如果是字符串或者两个d ...

  9. python基础——filter函数

    python基础——filter函数 Python内建的filter()函数用于过滤序列. 和map()类似,filter()也接收一个函数和一个序列.和map()不同的是,filter()把传入的函 ...

  10. python基础——匿名函数及递归函数

    python基础--匿名函数及递归函数 1 匿名函数语法 匿名函数lambda x: x * x实际上就是: def f(x): return x * x 关键字lambda表示匿名函数,冒号前面的x ...

随机推荐

  1. Scala For Java的一些参考

          变量 String yourPast = "Good Java Programmer"; val yourPast : String = "Good Java ...

  2. iOS之数字的格式化

    //通过NSNumberFormatter,同样可以设置NSNumber输出的格式.例如如下代码: NSNumberFormatter *formatter = [[NSNumberFormatter ...

  3. NSDateFormatter 时间格式转换

    NSString *strDate = @“Wed Apr ::”; NSDateFormatter *dateFomatter =[[NSDateFormatter alloc] init]; [d ...

  4. django 第三天 有关pip使用

    软件应用开发的经典模型有这样几个环境:开发环境(development).集成环境(integration).测试环境(testing).QA验证,模拟环境(staging).生产环境(product ...

  5. DX12龙书第6章习题

    1. { { , DXGI_FORMAT_R32G32B32_FLOAT, , , D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, }, { , DXGI_FO ...

  6. 关于WCF测试时出现无法从***获取元数据问题

    在我们已经创建成功一个WCF服务后,通过本机localhost访问和测试均没有任何问题.但是寄宿在IIS/其他平台下时便会出现以下的错误信息 1.使用WCF Test Client错误 2.通过C#引 ...

  7. 在Asp.net MVC 3 web应用程序中,我们会用到ViewData与ViewBag,对比一下:

    Asp.net MVC中的ViewData与ViewBag ViewData ViewBag 它是Key/Value字典集合 它是dynamic类型对像 从Asp.net MVC 1 就有了 ASP. ...

  8. Node.js 教程 06 - 函数

    前言: 本篇介绍的是Node.js中的函数,相对于上一篇会简单一点,其实和我们Javascript中的function无异. 好了,废话不多说了,我们进入正题吧. Node.js函数: [示例1:创建 ...

  9. 如何升级PowerShell

    背景: 开发的PowerShell 脚本需要使用Invoke-RestMethod命令,发现在老的服务器上不支持这一命令,经过查询得知由于PS版本的问题.涉及到了PS的升级,需要介绍下PowerShe ...

  10. 安装 log.io 实时监控 php_error 日志

    Log.io 实时监控 php_error.log 日志 开启 php_error 实时监控日志的第一步,要首先开启 php_error 的功能. vi php.ini 修改 PHP 配置文件,将 ; ...