-
昨天回顾
id(x) 函数
is / is not 运算符
-
函数式编程
-
高阶函数
map(函数, 可迭代对象) # 返回生成器对象
filter(函数, 可迭代对象) # 返回生成器对象(生成器对象是可迭代对象)
sorted(可迭代对象, key=None<函数>, reverse=False) # 返回列表
-
-
模块
-
导入模块
# 以 random 模块为例
# 1\.
import random
random.randint(1, 100)
random.choice([1, 2, 3, 4, 5])
# 2\.
from random import randint
randint(1, 100)
# 3\.
from random import *
randint(1, 100)
choice([1, 2, 3, 4, 5])
-
-
预置模块
- random 模块
- time 模块
- datetime 模块
异常
-
作用
用作信号通知,通知上层调用者有错误产生需要处理
try 语句
- 语法
-
作用
尝试捕获异常,得到异常通知,将程序由异常状态变为正常状态
-
说明
except 子句可以有 1个或多个
except: 不给错误类型,可以匹配全部的错误类型
else 子句里的语句会在 没有错误发生时执行,当处于异常时不执行
finally 子句里的语句,无论何时都执行
-
示例
try:
x = int(input("请输入一个整数:"))
print('x=', x)
except ValueError:
print('您的输入不能转成整数')
print("程序结束")
raise 语句
-
问题
# 写一个函数, get_score 函数,读取用户输入的整数成绩,
# 成绩的正常值是0~100 之间, 要求, 如果不在0~100 之间
# 报 ValueError类型的错误
def get_score():
x = int(input('请输入成绩:'))
if 0 <= x <= 100:
return x
raise ValueError('用户输入的成绩不在 0~100之间!') -
语法
raise 异常类型
或
raise 异常对象 -
作用
- 抛出一个错误,让程序进入异常状态
- 发送错误通知给调用者
-
说明
- 一旦raise 语句被调用,则raise 之后的语句将不会执行。
-
示例:
# 写一个函数, get_score 函数,读取用户输入的整数成绩,
# 成绩的正常值是0~100 之间, 要求, 如果不在0~100 之间
# 报 ValueError类型的错误
def get_score():
x = int(input('请输入成绩:'))
if 0 <= x <= 100:
return x
# raise ValueError
raise ValueError('用户输入的成绩不在 0~100 之间')
try:
score = get_score()
print(score)
except ValueError as err:
print("成绩输入有误 err=", err) -
异常类型的可选种类
字节串 bytes 和字节数组 bytearray
字节串的字面值
>>> b''
>>> b""
>>> b''''''
>>> b''''''
>>> b'ABC'
>>> bytes([65, 66, 67, 68])
>>> bytes([65, 66, 67, 68, 200,255])
>>> bytes([65, 66, 67, 68, 200,255, 300]) # 300 超出了255 报错
>>> bytearray([65, 66, 67, 68, 200,255]) # 字节数组的创建必须使用bytearray函数
-
字节串的运算
+ += * *=
> >= < <= == !=
in / not in
索引和切片
-
示例
>>> b = bytes([65, 66, 67, 68, 200,255])
>>> b
b'ABCD\xc8\xff'
>>> b[0]
65
>>> b[:2]
b'AB'
>>> b += b'123'
>>> b
b'ABCD\xc8\xff123'
>>> len(b)
9 -
bytes 和 str 的区别
-
bytes 与 str 转换
编码(encode)
str -------------> bytes
b = s.encode(encoding='utf-8')
解码(decode)
bytes -----------> str
s = b.decode(encoding='utf-8')示例
>>> s = 'hello 小张'
>>>
>>> b = s.encode() # 将字符串编码成为字节串
>>> b
b'hello \xe5\xb0\x8f\xe5\xbc\xa0' # 在utf-8 编码中,1个汉字通常用3个字节进行编码
>>> len(b)
12
>>> s2 = b.decode() # 将字节串解码成为字符串
>>> s2
'hello 小张'
文件
-
什么是文件
文件通常用来存储以字节为单位的数据
-
文件的操作流程
- 打开文件
- 读/写文件
- 关闭文件
-
打开文件用open 函数
open(file, mode='rt')
# open 函数返回文件流对象
# 打开失败回收到异常通知
# mode 的缺省值的 'rt'-
示例
myfile = open('/etc/passwd', 'rt')
s = myfile.read() # 用 myfile 绑定的文件流对象的read() 方法,得到 文件内部的数据
print(s)
myfile.close() # 关闭文件
-
-
两种操作文件的模式
-
直接用 字节串操作文件(内部可以存储文字,也可以存储图片等信息)
-
用字符串操作文本文件(内部存储的都是文字)
-
-
示例见
-
用字符串操作文件
f = open('mynote.txt', 'rt') # 'r 代表读
s = f.read() # 在't' 模式下 ,read 返回字符串
print(s)
f.close() # 关闭 -
用字节串操作文件
f = open('mynote.txt', 'rb') # 'r' 代表读 'b' 代表以二进制方式操作
b = f.read() # 在't' 模式下 ,read 返回字节串
print(b)
s = b.decode() # 将字节串转成了字符串
print(s)
f.close() # 关闭
-
-
文件的打开模式 mode
模式 说明 't' 以文本(字符串) 的模式操作文件(默认) 'b' 以二进制(字节串) 的模式操作文件 -
文件的打开方式 mode
方式 说明 'r' 读取文件(默认) 'w' 写和覆盖写文件(如果文件不存在则创建文件 ) 'a' 写并且追加文件内容(如果文件不存在则创建文件) python 文件流对象的方法
方法名 说明 F.close() 关闭文件 读取文件的方法 F.read(size=-1) 读取文件(不给出size 参数过读取全部) F.readline() 读取文件中的一行,以'\n' 作为行分隔符 F.readlines() 读取文件中的全部,以'\n' 作为行分隔符, 返回行的列表 写文件的方法 F.write(x) 写文件: 'b'模式 x 必须是字节串, 't'模式x必须是字符串, 如果文件不存在则新建文件 -
练习
我是老魏
我在 tarena
>>> f = open('mynote.txt', 'rb')
>>> f.read() # 返回全部
b'\xe6\x88\x91\xe6\x98\xaf\xe9\xad\x8f\xe7\x9c\x80\xe6\x8b\xa9\n\xe6\x88\x91\xe5\x9c\xa8 tarena\n'
>>> f.read() # 当到达文件尾部,返回空
b''
>>> f.close()
>>> f = open('mynote.txt', 'r')
>>> f.read()
'我是魏眀择\n我在 tarena\n'
>>> f.close()
>>> f = open('mynote.txt', 'r')
>>> f.readline() # 返回一行
'我是魏眀择\n'
>>> f.readline()
'我在 tarena\n'
>>> f.readline()
''
>>> f.close()
>>> f = open('mynote.txt', 'r')
>>> f.readlines() # 取出所有的行数据,返回列表
['我是魏眀择\n', '我在 tarena\n']
>>> f.close()
>>> f = open('python.log', 'w') # 以字符串方式写文件, 如果文件文件不存在回新建一个文件
>>> f.write('该吃饭了')
4
>>> f.write('!')
1
>>> f.write('\n') # 写一个换行
1
>>> f.write('下课')
2
>>> f.close()
-
移动文件的读写指针seek 方法
- 在读写二进制模式打开的文件,在不关闭文件的情况下, 可以使用seek 方法移动文件的读写指针
-
tell() 方法,返回文件的读写指针的位置
F.tell() # 返回整数
-
示例
1234567890ABCDE
myfile = open('mynote2.txt', 'rb')
print('刚打开文件时,文件指针的位置是:', myfile.tell()) # 0
b = myfile.read(2)
print(b) # b'12'
print('读取两个字节后,文件指针的位置是:', myfile.tell()) # 2
# 读取 67890 这个5个字节
# myfile.seek(5, 0) # 0 开始位置,向后移动5个字节
# myfile.seek(3, 1) # 1 当前位置,向后移动3个字节
myfile.seek(-10, 2) # 2 文件末尾位置,向前移动10个字节
print('myfile.seek()后,文件指针的位置是:', myfile.tell()) # 5
b = myfile.read(5) # b'67890'
print('myfile.read(5)后,文件指针的位置是:', myfile.tell()) # 10
print(b)
myfile.close()
with 语句
通过with 语句打开文件,with 语句结束,则文件会自动关闭
-
语法
-
示例
# file: mynote2.txt
# 不用with 语句
f = open('mynote2.txt')
s = f.read()
print(s)
f.close()
# 用with 语句
with open('mynote2.txt') as f:
s = f.read()
print(s)
sys模块
-
Shell 的位置参数
$0 $1 $2
-
python 上获取命令行参数
#! /usr/bin/python3
# file 04_myprog.py
import sys
print(sys.argv) # ['./04_myprog', '/root', 'hello']
# 如下是shell 中运行的内容
$ chmod +x myprog.py
$ ./myprog /root hello # $0='./04_myprog' $1='/root' $2='hello'
-
os 模块
- 对操作系统的访问大多使用 python 中的os 模块
>>> import os
>>> os.getcwd() # 返回当前的工作路径,pwd
'/root/桌面/py02/day03_code'
>>> os.mkdir('/tmp/nsd21xx') # mkdir /tmp/nsd21xx
>>> os.makedirs('/tmp/nsd21xx/a/b/c') # mkdir -p /tmp/nsd21xx/a/b/c
>>> os.listdir() # ls
['mygames.py', '.idea', 'mynote.txt', 'python.log', 'mynote2.txt', '03_file_seek.py', '04_myprog.py', '05_cp.py', '01_read_text_file_by_string.py', '02_read_text_file_by_bytes.py']
>>> os.listdir('/tmp') # ls /tmp # 列出所有的文件夹
[ 'nsd21xx', 'dir1', 'dir2']
>>> os.chdir('/tmp/nsd21xx') # cd /tmp/nsd21xx
>>> os.getcwd() # pwd
'/tmp/nsd21xx'
>>> os.symlink('/etc/passwd', '/tmp/abc') # ln -s /etc/passwd /tmp/abc
>>> os.mknod('/tmp/myfile.txt') # touch /tmp/myfile.txt
>>> os.chmod('/tmp/myfile.txt', 0o755) # chmod 755 /tmp/myfile.txt
>>> os.rename('/tmp/myfile.txt', '/tmp/a.txt') # mv /tmp/myfile.txt /tmp/a.txt
>>> os.rmdir('/tmp/dir2') # rmdir /tmp/dir2
>>> os.remove('/tmp/a.txt') # rm /tmp/a.txt
-
字符串用于去掉空白字符串的方法
>>> s = ' \n \t hello world \n'
>>> s.strip() # 去掉左右两侧的空白字符
'hello world'
>>> s.lstrip() # 去掉左侧的空白字符
'hello world \n'
>>> s.rstrip() # 去掉右侧的空白字符
' \n \t hello world'
os.path 模块
用于路径的操作的模块
>>> import os
>>> os.path.isabs('/root/abc.txt') # 判断是否为绝对路径
True
>>> os.path.isdir('/tmp/nsd21xx') # 判断是否是文件夹
True
>>> os.mknod('/tmp/b.txt') # touch /tmp/b.txt
>>> os.path.isfile('/tmp/b.txt') # 判断是否是文件
True
>>> os.path.islink('/tmp/abc') # 判断是否是软连接?
True
>>> os.path.ismount('/home') # 存在并且是挂载点
True
>>> os.path.exists('/root') # 判断文件或文件夹是否存在
True
>>> os.path.basename('/tmp/nsd21xx/hello.py') # 返回文件名
'hello.py'
>>> os.path.dirname('/tmp/nsd21xx/hello.py') # 返回路径
'/tmp/nsd21xx'
>>> os.path.split('/tmp/nsd21xx/hello.py') # 拆分 路径和文件名
('/tmp/nsd21xx', 'hello.py')
>>> os.path.join('/tmp/nsd21xx', 'world.py') # 拼接路径
'/tmp/nsd21xx/world.py'
os.walk() 函数
遍历文件夹
示例
>>> for x in os.walk('/tmp/nsd21xx'):
... print(x)
...
# (路径 , 路径内的所有文件夹列表 , 路径内的所有文件列表)
('/tmp/nsd21xx', ['a', 'aa'], [])
('/tmp/nsd21xx/a', ['b'], ['aaa.txt'])
('/tmp/nsd21xx/a/b', ['c'], ['bbb.txt'])
('/tmp/nsd21xx/a/b/c', [], [])
('/tmp/nsd21xx/aa', ['bb'], [])
('/tmp/nsd21xx/aa/bb', ['cc'], [])
('/tmp/nsd21xx/aa/bb/cc', [], [])
shutil 模块
>>> import shutil
>>> f1 = open('/etc/passwd', 'rb')
>>> f2 = open('/tmp/mypass.txt', 'wb')
>>> shutil.copyfileobj(f1, f2)
>>> f1.close()
>>> f2.close()
>>>
>>> shutil.copy('/etc/passwd', '/tmp/mypass2.txt') # cp /etc/passwd /tmp/mypass2.txt
'/tmp/mypass2.txt'
>>> shutil.copytree('/root/桌面/py02/day03_code', '/tmp/mycode') # cp -r /root/桌面/py02/day03_code /tmp/mycode
'/tmp/mycode'
>>> shutil.move('/tmp/mypass.txt', '/tmp/nsd21xx/a.txt') # mv /tmp/mypass.txt /tmp/nsd21xx/a.txt
>>> shutil.rmtree('/tmp/mycode') # rm -rf /tmp/mycode
>>> shutil.chown('/tmp/mypass.txt', user='xxx', group='yyy') # 改属主属组
-
课后练习:
生成器
生成器是在程序运行时生成数据,与容器不同,它通常不会在内存中保留大量的数据,而是现用现生成。
生成器有两种
- 生成器函数
- 生成器表达式
生成器函数
含有yield 语句的函数 是生成器函数,此函数调用回返回一个生成器对象,生成器也是可迭代对象
yield 语句的语法
生成器函数示例:
# 定义一个生成器函数, 有 yield 的函数调用后回返回生成器对象
def myrange(stop):
i = 0
while i < stop:
yield i # 为 遍历次生产器的for 语句提供数据
i += 1
for x in myrange(5):
print('x=', x)
生成器表达式
- 语法:
-
作用
用推导式的形式创建一个生成器
示例