# 有任何侵权问题,请私信我!
第一章
数值类型和序列类型
数值类型
int 整数的四则运算
float 小数
decimal 定点数(‘’)
bool 布尔类型(True或者false)
complex 复数 如4+5j
补充
% 模(取余数) 如:7 % 4 == 3;8 % 4 ==0
// 向下取整 如: 7 // 4 == 1
序列类型
字符串 不可改变类型
列表 可改变类型
元组 不可改变类型
索引取值
切片
作业
1、定义讲过的每种数值类型和序列类型
2、一个列表里有5个元素,用多种方法取到最后一个元素
3、有一个实践形式是(20170903),要求从这个格式中得到年、月、日
序列类型的方法
列表的方法
append 在列表末尾加一个元素 ,
insert 可增加元素在列表的指定位置
extend 可在列表中增加一个列表其中包含多个元素
clear 清除列表的全部元素
pop 括号里面什么都不加只移除最后一个元素 ;括号里加索引序号的移除索引位置的元素
remove 移除指定元素
index 查找指定元素的索引位置 ,有重复元素时只列出最前面一个
count 查找列表中的元素个数
copy 复制一份列表
reverse 将列表中的元素全部反转(从后往前排列)
sort 对列表中元素进行排序:数字从小到大,可包含负数;字母从a到z,
大写字母在最前面;汉字在最后;整数和字符串不能在一起排序,会报错
字符串方法
count 查找字符串中的元素个数
find 查找字符串中元素的索引,元素不存在时不会报错,返回-1
index 查找字符串中元素的索引,元素不存在时会报错
isdigit 查看字符串中是否全是数字
isalpha 查看字符串中是否全是字母,有空格时为False
endswith 查看字符串末尾的元素是否为输入的元素
startswith 查看字符串前面刚开始的元素是否为输入的元素
islower 查看字符串中的字母是否都是小写
isupper 查看字符串中的字母是否都是大写
upper 将字符串中的字母全部改为大写
lower 将字符串中的字母全部改为小写
strip (lstrip,rstrip) 将字符串前后的空格删除,lstrip只删除左边(前面)的空格
rstrip只删除右边(后面)的空格
capitalize 将字符串中首字母大写
title 将字符串中每个单词的首字母大写
split 将字符串以括号中的元素为对象进行分割
replace 将字符串中的某个元素进行替换
元组的方法
count 查找元组中的元素个数
index 查找元组中元素的索引,元素不存在时会报错
转义
\n 换行
\t 水平制表符
\b 退格
\r 回车,当前位置移到本行开头
\ 代表反斜杠
\' 代表一个单引号,同样的“ ? 等符号也可以这么输出
\o 代表一个空字符
\a 系统提示音
如果要去掉字符串的转义,只需要在字符串全面加上r
补充
encode 编码
decode 解码
作业
1、用多种方法往列表中插入值
2.列表['hallo', 'python', '!'],将hallo改成hello,并输出‘hello python !'
Python3 列表(可修改)
序列是Python中最基本的数据结构。序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推。
Python有6个序列的内置类型,但最常见的是列表和元组。
序列都可以进行的操作包括索引,切片,加,乘,检查成员。
此外,Python已经内置确定序列的长度以及确定最大和最小的元素的方法。
列表是最常用的Python数据类型,它可以作为一个方括号内的逗号分隔值出现。
列表的数据项不需要具有相同的类型
创建一个列表,只要把逗号分隔的不同的数据项使用方括号括起来即可。如下所示:
list1 = ['Google', 'Runoob', 1997, 2000];list2 = [1, 2, 3, 4, 5 ];list3 = ["a", "b", "c", "d"];
与字符串的索引一样,列表索引从0开始。列表可以进行截取、组合等。
访问列表中的值
使用下标索引来访问列表中的值,同样你也可以使用方括号的形式截取字符,如下所示:
list1 = ['Google', 'Runoob', 1997, 2000];
list2 = [1, 2, 3, 4, 5, 6, 7 ];
print ("list1[0]: ", list1[0])
print ("list2[1:5]: ", list2[1:5])
输出结果:
list1[0]: Google
list2[1:5]: [2, 3, 4, 5]
更新列表
你可以对列表的数据项进行修改或更新,你也可以使用append()方法来添加列表项,如下所示:
list = ['Google', 'Runoob', 1997, 2000]
print ("第三个元素为 : ", list[2])
list[2] = 2001
print ("更新后的第三个元素为 : ", list[2])
以上实例输出结果:
第三个元素为 : 1997
更新后的第三个元素为 : 2001
删除列表元素
可以使用 del 语句来删除列表的的元素,如下实例:
list = ['Google', 'Runoob', 1997, 2000]
print (list)
del list[2]
print ("删除第三个元素 : ", list)
以上实例输出结果:
删除第三个元素 : ['Google', 'Runoob', 2000]
Python列表脚本操作符
列表对 + 和 * 的操作符与字符串相似。+ 号用于组合列表,* 号用于重复列表。
如下所示:
Python 表达式 | 结果 | 描述 |
---|---|---|
len([1, 2, 3]) | 3 | 长度 |
[1, 2, 3] + [4, 5, 6] | [1, 2, 3, 4, 5, 6] | 组合 |
['Hi!'] * 4 | ['Hi!', 'Hi!', 'Hi!', 'Hi!'] | 重复 |
3 in [1, 2, 3] | True | 元素是否存在于列表中 |
for x in [1, 2, 3]: print(x, end=" ") | 1 2 3 | 迭代 |
Python列表截取与拼接
Python的列表截取与字符串操作类型,如下所示:
L=['Google', 'Runoob', 'Taobao']
操作:
Python 表达式 | 结果 | 描述 |
---|---|---|
L[2] | 'Taobao' | 读取第三个元素 |
L[-2] | 'Runoob' | 从右侧开始读取倒数第二个元素: count from the right |
L[1:] | ['Runoob', 'Taobao'] | 输出从第二个元素开始后的所有元素 |
列表还支持拼接操作:
>>>squares = [1, 4, 9, 16, 25]>>> squares + [36, 49, 64, 81, 100]
输出结果:
[ 1 , 4, 9, 16, 25, 36, 49, 64, 81, 100]
Python列表函数&方法
Python包含以下函数:
序号 | 函数 |
---|---|
1 | [len(list)]列表元素个数 |
2 | [max(list)]返回列表元素最大值 |
3 | [min(list)]返回列表元素最小值 |
4 | [list(seq)]将元组转换为列表 |
Python包含以下方法:
序号 | 方法 |
---|---|
1 | [list.append(obj)]在列表末尾添加新的对象 |
2 | [list.count(obj)]统计某个元素在列表中出现的次数 |
3 | [list.extend(seq)]在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表) |
4 | [list.index(obj)]从列表中找出某个值第一个匹配项的索引位置 |
5 | [list.insert(index, obj)]将对象插入列表 |
6 | [list.pop(obj=list[-1])移除列表中的一个元素(默认最后一个元素),并且返回该元素的值 |
7 | [list.remove(obj)]移除列表中某个值的第一个匹配项 |
8 | [list.reverse()]反向列表中元素 |
9 | [list.sort([func])]对原列表进行排序 |
10 | [list.clear()]清空列表 |
11 | [list.copy()]复制列表 |
Python3 元组(不可修改)
Python 的元组与列表类似,不同之处在于元组的元素不能修改。
元组使用小括号,列表使用方括号。
元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。
如下实例:
tup1 = ('Google', 'Runoob', 1997, 2000);
tup2 = (1, 2, 3, 4, 5 );
tup3 = "a", "b", "c", "d";
创建空元组
tup1 = ();
元组中只包含一个元素时,需要在元素后面添加逗号,否则括号会被当作运算符使用:
>>> tup1 = (50)
>>> type(tup1) # 不加逗号,类型为整型
<class 'int'>
>>> tup1 = (50,)
>>> type(tup1) # 加上逗号,类型为元组
<class 'tuple'>
元组与字符串类似,下标索引从0开始,可以进行截取,组合等。
访问元组
元组可以使用下标索引来访问元组中的值,如下实例:
#!/usr/bin/python3
tup1 = ('Google', 'Runoob', 1997, 2000)
tup2 = (1, 2, 3, 4, 5, 6, 7 )
print ("tup1[0]: ", tup1[0])
print ("tup2[1:5]: ", tup2[1:5])
以上实例输出结果:
tup1[0]: Google
tup2[1:5]: (2, 3, 4, 5)
修改元组
元组中的元素值是不允许修改的,但我们可以对元组进行连接组合,如下实例:
tup1 = (12, 34.56);
tup2 = ('abc', 'xyz')
# 以下修改元组元素操作是非法的。
# tup1[0] = 100
# 创建一个新的元组
tup3 = tup1 + tup2;
print (tup3)
以上实例输出结果:
(12, 34.56, 'abc', 'xyz')
删除元组
元组中的元素值是不允许删除的,但我们可以使用del语句来删除整个元组,如下实例:
tup = ('Google', 'Runoob', 1997, 2000)
print (tup)
del tup;
print ("删除后的元组 tup : ")
print (tup)
以上实例元组被删除后,输出变量会有异常信息,输出如下所示:
删除后的元组 tup :
Traceback (most recent call last):
File "test.py", line 8, in <module>
print (tup)
NameError: name 'tup' is not defined
元组运算符
与字符串一样,元组之间可以使用 + 号和 * 号进行运算。这就意味着他们可以组合和复制,运算后会生成一个新的元组。
Python 表达式 | 结果 | 描述 |
---|---|---|
len((1, 2, 3)) | 3 | 计算元素个数 |
(1, 2, 3) + (4, 5, 6) | (1, 2, 3, 4, 5, 6) | 连接 |
('Hi!',) * 4 | ('Hi!', 'Hi!', 'Hi!', 'Hi!') | 复制 |
3 in (1, 2, 3) | True | 元素是否存在 |
for x in (1, 2, 3): print x, | 1 2 3 | 迭代 |
元组索引,截取
因为元组也是一个序列,所以我们可以访问元组中的指定位置的元素,也可以截取索引中的一段元素,如下所示:
元组:
L = ('Google', 'Taobao', 'Runoob')
Python 表达式 | 结果 | 描述 |
---|---|---|
L[2] | 'Runoob' | 读取第三个元素 |
L[-2] | 'Taobao' | 反向读取;读取倒数第二个元素 |
L[1:] | ('Taobao', 'Runoob') | 截取元素,从第二个开始后的所有元素。 |
运行实例如下:
>>> L = ('Google', 'Taobao', 'Runoob')
>>> L[2]
'Runoob'
>>> L[-2]
'Taobao'
>>> L[1:]
('Taobao', 'Runoob')
元组内置函数
Python元组包含了以下内置函数
序号 | 方法及描述 | 实例 |
---|---|---|
1 | len(tuple)计算元组元素个数。 | >>> tuple1 = ('Google', 'Runoob', 'Taobao')>>> len(tuple1)3>>> |
2 | max(tuple)返回元组中元素最大值。 | >>> tuple2 = ('5', '4', '8')>>> max(tuple2)'8'>>> |
3 | min(tuple)返回元组中元素最小值。 | >>> tuple2 = ('5', '4', '8')>>> min(tuple2)'4'>>> |
4 | tuple(seq)将列表转换为元组。 | >>> list1= ['Google', 'Taobao', 'Runoob', 'Baidu']>>> tuple1=tuple(list1)>>> tuple1('Google', 'Taobao', 'Runoob', 'Baidu') |
decimal模块
简介
decimal意思为十进制,这个模块提供了十进制浮点运算支持。
常用方法
1.可以传递给Decimal整型或者字符串参数,但不能是浮点数据,因为浮点数据本身就不准确。
2.要从浮点数据转换为Decimal类型
from decimal import *
Decimal.from_float(12.222)
# 结果为Decimal('12.2219999999999995310417943983338773250579833984375')
示例:
import decimal
a = decimal.Decimal('1.2')
b = decimal.Decimal('1')
a - b
返回Decimal('0.2')
3.通过设定有效数字,限定结果样式:
from decimal import *
getcontext().prec = 6
Decimal(1)/Decimal(7)
# 结果为Decimal('0.142857'),六个有效数字
4.四舍五入,保留几位小数
from decimal import *
Decimal('50.5679').quantize(Decimal('0.00'))
# 结果为Decimal('50.57'),结果四舍五入保留了两位小数
5.Decimal 结果转化为string
列表常用方法总结
li = ['xiao','jiu',1,2,3] (示例中不叠加使用,每一次都会定义原始的列表)
类型 | 用法 | 方法 | 示例 |
---|---|---|---|
增 | append | 添加 | >li.append(4) >li >['xiao', 'jiu', 1, 2, 3, 4] |
insert | 索引插入 | >li.insert(3,'nanbei') >li >['xiao', 'jiu', 1, 'nanbei', 2, 3] | |
extend | 添加多个元素到末尾[] | >li.extend([666,999]) >li >['xiao', 'jiu', 1, 2, 3, 666, 999] | |
删 | clear | 清除 | >li.clear() >li >[] |
pop | 索引删除(无索引时默认删除最后一位) | >li.pop(3) >li >['xiao', 'jiu', 1, 3] | |
remove | 指定删除 | >li.remove(3) >li >['xiao', 'jiu', 1, 2] | |
改 | li[索引] = 赋值 | 索引取值并重新赋值 | >li[3] = '6' >li >['xiao', 'jiu', '6', 2, 3] |
查 | index | 用值得到索引 (默认第一个符合条件的值,()中没有元素会报错)) | >li.index('jiu') >1 |
count | 计算元素出现次数 | >li.count(3) >1 | |
复制 | copy | 复制 (复制出来的和原来不是同一个) | >li.copy >li >['xiao','jiu',1,2,3] |
排序 | reverse | 调转列表顺序(改变列表本身) | >li.reverse() >li >[3, 2, 1, 'jiu', 'xiao'] |
sort | 排序 (li = [2,4,14,5,6]) | >li.sort() >li >[2, 4, 5, 6, 14] |
元组的常见方法
a = (1,2,3,4,5) (可改成列表进行操作)
b = list(a)
a = tuple(b)
类型 | 用法 | 方法 |
---|---|---|
count | 计算元素出现次数 | >a.count(3) >1 |
index | 用值得到索引 (默认第一个符合条件的值,()中没有元素会报错) | >a.index(2) >1 |
字符串常见用法总结
注(字符串本身不可变,需用变量接收)
a = 'xiaojiu'
b = '12345'
c = ' xiao jiu '
d = 'xiao,jiu,666,888'
类型 | 用法 | 方法 | 示例 |
---|---|---|---|
查 | count | 计数 | >a.count('i') >2 |
find | 查找(返回索引) | >a.find('o') >3 (括号中元素若字符串中没有会返回-1) | |
index | 查找(返回索引) | >a.index('o') >3 (括号中元素若字符串中没有会报错) | |
isdigit | 是否都为数字 | >b.isdigit() >True | |
isalpha | 是否都为字母 | >a.isalpha() >True | |
endswith | 是否以('')中的内容结尾 | >a.endswith('jiu') >True | |
startswith | 是否以('')中的内容开始 | >a.startswith('x') >True | |
islower | 是否都为小写 | >a.islower() >True | |
isupper | 是否都为大写 | >a.isupper() >False | |
改 | upper | 全部转变为大写 | >e = a.upper() >e >'XIAOJIU'(字符串本身不可变,需用变量接收) |
lower | 全部转变为小写 | >a = b.lower() >a >'xiaojiu'(字符串本身不可变,需用变量接收) | |
strip | 删除头尾空格 | >c.strip() >'xiao jiu' | |
lstrip | 删除左边空格 | >c.lstrip() >'xiao jiu ' | |
rstrip | 删除右边空格 | >c.rstrip() >' xiao jiu' | |
capitalize | 大写首英文字符 | >a.capitalize() >'Xiaojiu' | |
title(标题) | 大写每一个英文字符的首字符 | >c.title() >' Xiao Jiu ' | |
*split | 以 (' ') 进行分割 | >d.split(',') >['xiao', 'jiu', '666', '888'] | |
删 | replace | 替换(把原字符替换为空字符可进行删除,如示例2) | 1. >a.replace('xiao','da') >'dajiu' 2. >a.replace('xiao','') >'jiu' |
增 | 字符串拼接 | + ,格式化,join ,format | >a + b >'xiaojiu12345' |
字符串的转义
符号 | 用法 | 示例 |
---|---|---|
\\ | 代表\ | >f = 'abc\\123' >print(h) >abc\123 |
\0 | 代表一个空字符 | >g = 'abc\0123' >print(f) (输出可看到结果,格式问题不方便写入,请自行操作查看) |
\a | 系统提示音 | >h = '\a' >print(z) (会听到提示音) |
\b | 退格 | >i = 'abc\b123 >print(i) >ab123 |
\n | 换行 | >j = 'abc\n123' >print(f) (输出可看到结果,格式问题不方便写入,请自行操作查看) |
\r | 回车,当前位置移到本行开头 | >k = 'abcdef\r123' >print(k) >123def ( 先写abcdef,\r,这时光标回到本行起始位置也就是a的位置,接着写123。abc此时会被123覆盖) |
\t | 水平制表符 | >l = 'abc\t123' >print(l) >abc 123 |
\' | 代表一个 ' 同样 " ? 也可以这样输出 | >m = 'abc\'123' >print(m) >abc'123 |
r | 字符串前面加r,取消转义 | >n =r 'abc\t123 ' >print(n) >abc\t123 |
Linux常用命令
常用命令 | 用途 | |
---|---|---|
hostname | 主机名 | |
sudo reboot | 重启 | |
whoami | 当前用户 | |
cat /etc/passwd | 查看当前用户 | |
su 帐户名 | 切换用户 | |
sudo useradd -m nanbei | 添加用户 | |
sudo visudo 或 sudo adduser nanbei sudo | 为普通用户添加root权限 | |
sudo usermod -l xiaojiu1 xiaojiu | 更改用户名 | |
sudo userdel username | 删除用户 | |
sudo userdel -r username | 删除用户,以及all | |
pwd | 查看当前目录 | |
cd .. | 回到上一级目录 | |
cd / | 跳到根目录 | |
cd /home/pyvip/py | 查找目录 | |
cd ~ | 回到家目录 | |
cd - | 类似cd ~但会返回目录名 | |
cd test | 进入文件夹 | |
cat test.py | 可以直接在终端把文件内容打印出来(获取文件内容) | |
ll | 查看当前文件子文件 在Ubuntu中其实是 ls -alF 的别名 | |
ls | 查看当前目录中的内容 | |
ls -a | 显示所有档案及目录(隐藏文件) | |
ls -c | 与“-lt”选项连用时,按照文件状态时间排序输出目录内容,排序的依据是文件的索引节点中的ctime字段。与“-l”选项连用时,则排序的一句是文件的状态改变时间; | |
ls -C | 多列显示输出结果 | |
ls -d | 仅显示目录名,而不显示目录下的内容列表。显示符号链接文件本身,而不显示其所指向的目录列表 | |
ls -f | 此参数的效果和同时指定“aU”参数相同,并关闭“lst”参数的效果 | |
ls -F | 在每个输出项后追加文件的类型标识符,具体含义:“*”表示具有可执行权限的普通文件,“/”表示目录,“@”表示符号链接,“|”表示命令管道FIFO,“=”表示sockets套接字。当文件为普通文件时,不输出任何标识符 | |
ls -k | 以KB(千字节)为单位显示文件大小 | |
ls -l | 单列显示输出结果 | |
ls -L | 如果遇到性质为符号链接的文件或目录,直接列出该链接所指向的原始文件或目录 | |
ls -r | 以文件名反序排列并输出目录内容列表 | |
ls -s | 显示文件和目录的大小,以区块为单位 | |
ls -t | 用文件和目录的更改时间排序 | |
ls -R | 递归处理,将指定目录下的所有文件及子目录一并处理 | |
ls -lrt | 最新更改的文件在最下面 | |
mkdir test(数字字母下划线) | 创建文件夹(不需要后缀名) | |
rmdir test | 删除文件夹 | |
rm -rf test | 强制删除文件或目录 | |
touch file | 创建文件 | |
nano file | 添加内容 ctrl+x退出 y保存 回车 | |
rm -d | 直接把欲删除的目录的硬连接数据删除成0,删除该目录 | |
rm -i | 删除已有文件或目录之前先询问用户 | |
rm -r或-R | 递归处理,将指定目录下的所有文件与子目录一并处理 | |
cp a.txt b.txt | 复制 a.txt 的内容到 test/b.txt 文件内 | |
mv a.txt b.txt | 移动 a.txt 到test 文件下 | |
help cd | 帮助 | |
man cd | 帮助 | |
workon | 1.查看虚拟环境(进入虚拟环境workon py3env) | |
deactivate | 退出虚拟环境(ctrl+c返回) | |
source ~/.virtualenvs/py3env/bin/activate | 2.进入虚拟环境(切换虚拟环境quit()或exit()重回linux | |
ctrl+l | 清屏 | |
2.网络 | 作用 | 示例 |
ifconfig | 配置和显示网络参数 | ifconfig |
wget | 从URL下载文件 | wget https://bootstrap.pypa.io/get-pip.py |
telnet | 登录远程主机 | telnet 127.0.0.1 1234 |
ping | 测试网络连通性 | ping 8.8.8.8 |
netstat | 网络系统的状态 | netstat -at |
route | 显示并配置路由表 | route -n |
ip | 网络配置工具 | ip addr |
curl | 下载工具 | curl https://www.shiguangkey.com/ |
ssh | ssh客户端连接工具 | ssh pyvip@127.0.0.1 -p 22 |
iptables | 防火墙配置 | service iptables stop |
3.系统管理 | 作用 | 示例 |
sudo | 默认以root权限执行命令 | sudo apt-get update |
ps | 查看进程状态 | ps -ef |
crontab | 定时任务 | crontab -l |
halt | 关机 | halt |
umount | 卸载已经挂载的文件 | umount /dev/sda |
passwd | 修改密码 | passwd pyvip |
reboot | 重启 | reboot |
su | 切换用户 | su root |
shutdown | 关机命令 | shutdown -h |
poweroff | 关机并断电 | poweroff |
useradd | 添加用户 | useradd pyvip |
usermod | 修改用户 | usermod pyvip pyvip2 |
userdel | 删除用户 | userdel pyvip |
groupadd | 添加用户组 | groupadd pyvip |
groupdel | 删除用户组 | groupdel pyvip |
groupmod | 修改用户组 | groupmod pyvip |
4.软件、打印、开发和工具 | 作用 | 示例 |
xargs | 将输入数据装换成命令行参数,一般是组合使用 | find ./ * |xargs grep 'soft' |
awk | 处理文本和数据的利器,Linux命令三剑客之一 | cat install.sh |awk '{print $1}' |
date | 显示或设置系统时间与日期 | date |
clear | 清屏 | clear |
whoami | 当前用户名 | whoami |
sleep | 暂停指定时间 | slepp 1 |
who | 当前用户信息 | who |
5.文件和目录管理 | 作用 | 示例 |
iconv | 转换文件编码 | iconv install.sh -f UTF-8 -t GBK -o install.sh.bak |
grep | 文本搜索,Linux命令三剑客之一 | grep "then" *.sh |
tree | 树状图列出目录的内容 | tree |
zip | 解压缩文件 | zip -q -r config.zip config |
unzip | 解压zip文件 | unzip config.zip |
tar | 打包 | tar cvf config.tar config |
gzip | 解压缩文件,后缀为.gz | gzip install.sh |
scp | 远程拷贝文件 | scp pyvip@127.0.0.1:/home/pyvip/install.sh /tmp |
wc | 显示字数,列数和Bytes数 | wc install.sh |
sort | 将文件内容排序 | sort install.sh |
cut | 显示文件指定的部分 | cut -c1-4 install.sh |
which | 查找命令的绝对路径 | which ls |
sed | 流编辑器,Linux命令三剑客之一 | sed -i 's/#/##/g' install.sh |
find | 查找指定目录下的文件 | find ./ -name "*.py" |
chmod | 更改文件或目录的权限 | chmod 664 install.sh |
tail | 查看文档结尾,一般默认10行 | tail -f install.sh |
whereis | 定为命令的二进制程序,源代码和man手册等绝对路径 | whereis ls |
chown | 改变文件或目录的属组 | chown -R pyvip:pyvip install.sh |
pwd | 显示当前的绝对路径 | pwd |
vim | 编辑器 | vim install.sh |
ln | 创建链接 | ln -s install.sh install |
6.硬件、内核、shell和监测 | 作用 | 示例 |
sh | shell命令语言解释器 | sh install.sh |
bash | 大多数Linux默认shell | bash install.sh |
du | 查看使用空间 | du -d 1 -h |
lsof | 查看打开的文件的情况 | lsof -i:22 |
time | 统计命令所花费的时间 | time ls |
free | 显示内存使用情况 | free |
top | 动态查看系统运行情况 | top |
bg | 将作业放到后台 | bg(执行top,然后按CTRL+Z,就可以使用bg,jobs,fg查看现象) |
jobs | 显示任务列表和任务状态 | jobs |
history | 显示历史命令 | history |
uname | 打印系统相关信息 | uname -a |
kill | 删除执行中的程序或工作 | kill -9 12343 |
alias | 设置指令的别名 | alias cd=‘rm -rf’ |
fg | 将后台作业放到终端 | fg |
echo | 输出 | echo hello |
df | 显示磁盘分区使用情况 | df -h |
ulimit | 限制用户对资源的访问 | ulimit -a |
man的命令 | 用途 |
---|---|
sudo yum install man | 安装man |
e | 下一行 |
y | 上一行 |
空格 或 f 或 z | 下一页 |
b 或 w | 上一页 |
/string | 向下搜寻string这个字符串 |
?string | 向上搜寻string这个字符串 |
n,N :n | 继续下一个搜寻,N进行反向搜寻 |
h | 帮助信息 |
q | 退出 |
虚拟环境中vim的使用命令 | 用途 |
---|---|
vim +filename | 进入文件(默认最后一行) |
vim +n +filename | 进入文件第n行 |
i | 输入模式,从光标所在位置前面开始插入 |
a | 输入模式,从光标所在位置后面插入 |
A | 输入模式,在当前行尾插入 |
l | 输入模式,在当前行首插入 |
o | 输入模式,在光标所在行下方新增一行插入 |
O | 输入模式,在光标所在行上方新增一行插入 |
0 | 移动光标到行首 |
s | 移动光标到行尾 |
gg | 移动光标到文件第一行 |
G(shift+g) | 移动光标到文件最后一行 |
yy | 复制整行内容 |
3yy | 复制3行内容 |
yw | 复制当前光标到单词尾 |
p | 粘贴 |
Esc | 命令模式(退出当前模式到命令模式) |
ZZ | 保存退出 |
:r +filename | 读入一个文件内容并添加到当前编辑器中 |
:w newfilename | 将该编辑器内容写入新文件中 |
:w | 在编辑过程中保存文件 |
:wq | 保存退出 |
:q | 直接退出 |
:q! | 强制退出 |
:!ls | 在编辑过程中执行shell命令ls |
:sh | 进入shell,执行完ctrl+d退出shell进入vim |
:set number 或 :set nu | 使编辑中的文件显示行号(相反 :set nonumber 或 :set nonu) |
:help i | 查看插入命令帮助 |
:/xiaojiu | 查找xiaojiu字符,向前搜索 |
:? | 同上,向后搜索 |
n | 向下搜索 |
N | 向上搜索 |
:s /xiaojiu/xiaojiu1 | 将xiaojiu替换为xiaojiu1 |
:1, . s/xiaojiu/xiaojiu1 | 将第一行到当前行 '第一次' 出现的xiaojiu替换为xiaojiu1 |
:1, %s/xiaojiu/xiaojiu1/g或 :%s/xiaojiu/xiaojiu1/g | 将第一行到当前行 '所有' 出现的xiaojiu替换为xiaojiu1(g为全局标志) |
dw | 删除光标到单词末尾 |
dd | 删除光标所在行 |
x | 删除光标所在字符 |
u | 撤销上一步 |
ctrl +r | 反撤销 |
v | 块选择 |
ctrl +v | 列块选择 |
python filename.py(shell模式) | 运行vim文件 |
注:vim中如果esc命令无效,则可能是其他软件屏蔽了esc的功能需按ctrl+c恢复。
rm -rf */删除系统 = 重装(温馨提示:请勿尝试)
bytes和bytearray
类型 | 示例 | 返回值 |
---|---|---|
bytes二进制序列类型 | bytes(3) | b'\x00\x00\x00' |
bytes(b'xiaojiu') | b'xiaojiu' | |
bytearray二进制数组 | bytearray(3) | bytearray(b'\x00\x00\x00') |
bytearray(b'xiaojiu') | bytearray(b'xiaojiu') |
代码转换(GBK转UTF-8)
'谭州' .encode(encoding='utf-8')
a = '谭州' .encode('GBK')
a
b = a.decode('GBK')
b
'谭州' #返回
进入虚拟环境
进入虚拟环境: workon py3env
安装ipython: pip install ipython # ipython的安装(交互式解释器)python
直接输ipython (ipython为python的升级版)
退出ipython: exit()
重回Linux : deactivate #退出虚拟环境(ctrl+c返回)
格式化输出
format {}中可以索引,也可指定一个变量
format的几种用法 | 用途 |
---|---|
'name:{},age:{}'.format('xiaojiu','baomi') | 传统用法 |
'{:.2f}'.format(12.123) | 类似%.2s(.2为控制精度) |
'{a:.2f}'.format(a=12.123) | —— |
'{:.2%}'.format(12.123) | 转换为百分比格式 |
'{0:o}'.format(12) | 转换为八进制 |
'{0:x}'.format(12) | 转换为十六进制 |
'{a:<10}' .format(a=12.3) | 左对齐,长度为10(>右对齐,^两边对齐) |
'{a:0<10}' .format(a=12.3) | 数字0补齐(填充右边,宽度为10) |
'{{hello {0} }}'.format('python') | 转义{}符号 |
1. f = 'hello {0}'.format或 f = 'name:{}'.format | 以后可直接进行以下操作 |
2. f('python') 或 f('xiaojiu') | 这里可以把format当成一个函数来看 |
字符串拼接%s
传统类型 | 用法 |
---|---|
%s | %字符串 |
%d | %数字 |
%f | %浮点数 |
%c | %ASCLL字符 |
%o | %8进制 |
%x | %16进制 |
%e | %科学记数法 |
%.2s | 控制字符串精度为2 |
##用法示例
name = 'xiaojiu'
'hello %s'%name
'hello xiaojiu'
today is %s,i am %s'%('thursday','xiaojiu')
'today is thursday,i am xiaojiu'
'today is %d,i am %s'%(4,'xiaojiu')
'today is 4,i am xiaojiu'
join(列表与可迭代对象使用)
##用法示例
li=('today', 'is', '4','xiaojiu')
'-'.join(li)
'today-is-4-xiaojiu'
可变与不可变、散列类型、运算符优先级、逻辑运算
可变与不可变
分类 | 类型 |
---|---|
不可变(immutable) | 整型 (int) |
字符串 (string) | |
浮点型 (float) | |
数值型 (numbei) | |
元组型 (tuple) | |
可变(mutable) | 列表型 (list) |
字典型 (dictionary) | |
集合型 (set) |
集合(散列类型)
特点:无序性 唯一性
集合的定义方法: set()
方法 | 示例 |
---|---|
1. 一般方法的定义 | >a = {'666','777'} |
2. 空集合的定义 | >c = set() |
>b = {} #注:类型为字典dict而不是集合 |
集合的运算方式
e = {111,222,333,444,555}
f = {444,555,666,777,888}
方式 | 示例 |
---|---|
交集 s1 % s2 | >e & f >{444,555} |
并集 s1 | s2 | >e | f >{111,222,333,444,555,666,777,888} |
差集 s1 - s2 | >e - f >{111,222,333} |
集合的常用方法
e = {111,222,333,444,555}
f = {444,555,666,777,888}
g = {111,222}
类型 | 用法 | 方法 | 示例 |
---|---|---|---|
增 | add | 添加一个可迭代元素 | >e.add('xiaojiu') >e >{111,222,333,444,555,'xiaojiu'} |
update | 添加(更新)多个可迭代元素,不能直接填一个元素 | >e.update(555,666) >e >{111,222,333,444,555,666,'xiaojiu'} | |
删 | pop | 随机删除(不可索引) | >e.pop() >666 |
remove | 指定移除 | >e.remove('xiaojiu') >e >{111,222,333,444,555} | |
查 | isdisjoint | 有交集返回False | >f.isdisjoint(g) >True |
issubset | 判断是否包含于 | >g.issubset(e) >True | |
issuperset | 判断是否包含 | >e.issuperset(g) >True |
字典(散列类型)
特点:键唯一 (必为不可变类型) 值无规则 无序
字典的定义方法
方法 | 示例 |
---|---|
1. 键值对的形式 | >a = {'name':'xiaojiu','age':18,'height':199} >a['age'] >18 (输入键来找值) |
2. 定义一个空字典 | >b = {} |
3. 使用dict函数 | >c = dict(nanbei='laoshi',juhao='laoshi') >c >{‘nanbei’='laoshi',‘juhao’='laoshi'} |
字典的常用方法
a = {'name':'xiaojiu','age':18}
b = {(1,2):'555'}
(示例每一次均重新定义,不叠加)
类型 | 用法 | 方法 | 示例 |
---|---|---|---|
添加 | di['a'] = 2 | - | >a['height'] = 210 >a >a = {'name':'xiaojiu','age':18,'height':210} |
修改 | di['b'] = 3 | - | >a['height'] = 210 >a >a = {'name':'xiaojiu','age':18,'height':210} |
增 | copy | 浅拷贝 | >d = b.copy() >b[(1,2)] = 100 >b >{(1,2):100} >d >{(1,2):'555'} |
setdefault | (有则查,无则增) | >a.setdefault('hello',888) >a >{'name':'xiaojiu','hello':888,'age':18} | |
删 | clear | 清除 | >a.clear >a >{} |
pop | 指定删除 | >a.pop('age') >a >{'name':'xiaojiu'} | |
popitem | 随机删除 | >a.popitem >('name':'xiaojiu') | |
改 | update | 添加(更新,拼接) | >a.update({'height':199}) >a >{'name':'xiaojiu','age':18,'height':199} |
查 | get | 存在返回,不存在返回none | >a.get('age') >18 |
keys | 取出所有键名(不支持索引,需转换成列表) | >a.keys >dict_keys(['name', 'age']) | |
value | 取出所有值(不支持索引,需转换成列表) | >a.value >dict_value(['xiaojiu', '18']) | |
items | 取出[()]形式的列表(for循环时用) | >e = a.items >e >divt_items([('name','xiaojiu'),('age',18)]) |
逻辑运算符
a = 1
b = 1
c = 2
isinstance() 与 type() 区别:
type() 不会认为子类是一种父类类型,不考虑继承关系。
isinstance() 会认为子类是一种父类类型,考虑继承关系。
如果要判断两个类型是否相同推荐使用 isinstance()。
类型 | 用法 | 方法 | 示例 |
---|---|---|---|
查看对象型 | type | 查看类型 | >typr(1) >int |
isinstance | 判断是否为某个类型 | > isinstance (a,str) > False | |
比较运算符 | == | 判断是否相等 | >a == b >True |
!= | 判断是否不等 | >a == c >True | |
判断语句(若有多个条件) | 判断语句1 and 判断语句2 | 判断是否前后都正确 | >a ==c and a ==b >False |
判断语句1 or 判断语句2 | 只有有一个正确就返回True,两边都错返回False | >a ==c or a ==b >True | |
not判断语句1 | 把逻辑反转 | >not a == b >False |
运算符优先级
python中的运算符(先运行的用括号括起来)
运算符 | 描述 |
---|---|
** | 幂运算 |
+ - | 一元运算 (正负号) |
* / % | 算术运算符 |
+ - | 算术运算符 |
< > <= >= | 比较运算符 |
== != | 比较运算符 |
= %= /= -= += *= **= | 赋值运算符(缩写) |
is is not | 身份运算符 |
in not in | 成员运算符 |
not>and>or | 逻辑运算符 |
控制流程
条件判断
语法结构 | 用途 | 示例 (a = 15) |
---|---|---|
if : | 判断语句1: | if a > 5 and a < 10: |
执行语句(缩进4个空格) | 执行语句1 | print('a比5大,比10小') |
elif : | 判断语句2: | elif a >= 10: |
执行语句2 | 执行语句2 | print('a比10大') |
…… | …… | …… |
else : | 判断语句3: | else: |
执行语句n | 执行语句n | print('a比5小') |
注:
符合条件就不会向下执行
若缩进一样则代表同一个代码块,运行时一起
三目运算
语法结构:b = 值1 if 判断语句 else 值2 (if成立返回值1,不成立返回值2)
示例:
条件判断(多个条件时) | 三目运算(只有一个条件时) |
---|---|
a = 3 | a = 3 |
if a > 5: | b = True if a>5 else False |
b = True | print(b) |
else: | |
b = False |
条件循环
while循环
示例1 | 注释 |
---|---|
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] | |
i = 0 | #a的索引 |
while a[i] <5: | #判断语句 |
print([a[i]]) | #循环体 |
i += 1 | |
#示例2 | #注释 |
a = [1, 2, 100, 34, 56, 5, 78, 7] | |
i = 0 | |
bigger_then_20 = [] | |
while i < 10: | 或者while i < len(a): 控制索引超出会报错 |
if a[i] == 20: | |
break | 停止循环 |
if a[i] > 20: | |
print('{}大于20'.format(a[i])) | |
bigger_then_20.append(a[i]) | |
else: | 没有break时,正常执行 |
print('{}小于20'.format(a[i])) | |
i += 1 | |
print(bigger_then_20) |
迭代循环
for循环
for后需要可迭代对象(list, tuple, str, set, dic(默认取出键keys,取值可用items, values)), 数值不可迭代
示例 | 注释 |
---|---|
li = [1, 2, 3, 4, 5, 6] | 定义 |
for i in li: | 循环体,或for i in range(1, 7): |
if i == 3: | 条件 |
continue | 跳过当前循环 |
print(li) | 结果 |
函数基础
一,函数的定义
-
命名规则:字母,数字,下划线组成
a = 10
if a>5:
print('a 这个数大于5')
else:
print('a 小于5')
# 运行结果:a 这个数大于5
(一)封装为函数,直接打印
# 定义函数
def decide(a):
if a>5:
print(‘a 这个数大于5’)
else:
print('a 小于5')
# 使用函数
a = 10
decide(a)
# 运行结果:a 这个数大于5
(二)return
-
多数情况下,我们需要函数处理后的结果,return 即退出函数并返回一个结果。
# 定义函数
def decide(a):
if a>5:
return '这个数大于5’
else:
return '这个数小于5’
# 使用函数
result = decide(4)
print(resualt)
result = decide(200)
print(resualt)
运行结果:
这个数小于5
这个数大于5
-
也可多个参数返回
# 定义函数
def today(num1,num2):
return num1,num2
# 使用函数
num1,num2 = today(10,20)
print(num1)
print(num2)
运行结果:
10
20
(三) pass (临时跳过)
# 定义函数
def decide(a):
if a>5:
pass
else:
return '这个数小于5’
(四)控制参数类型
-
判断传入参数类型,然后根据判断结果再运行函数内容
# 定义函数
def today(my_str):
if my_str is str:
return('今天是:',my_str)
# 使用函数
print(today(2))
运行结果:
None
二,参数的形式
(一)不传参数
-
调用时也不能传参
# 定义函数
def fun1():
print('不能传参数')
# 使用函数
fun1()
运行结果
不能传参数
(二)必备参数
-
此时num即为必备参数,直接调用fun1()会出错
# 定义函数
def fun1(num):
return '今天天气真好'+num
# 使用函数
print(fun1('xyz'))
(三)默认参数
-
调用时可传可不传,也可指定(例:word='123')
# 定义函数
def fun1(word = 'hehe'):
return '今天天气真好'+word
# 1 使用函数
print(fun1())
运行结果:
今天天气真好hehe
# 2 使用函数
print(fun1('haha'))
运行结果:
今天天气真好haha
(四)不定长参数(可传0到多个)
1.可选参数
-
函数自动将结果包装成了元组,加个*会把里面解包,参数为字典则会只返回键。
# 定义函数
def fun1(*args):
print(args)
# 1 使用函数
fun1(1,2,3,4,5,6)
运行结果:
(1,2,3,4,5,6)
# 2 使用函数
fun1(*(1,2,3,4,5,6))
运行结果:
(1,2,3,4,5,6)
# 3 使用函数
fun1(*[1,2,3,4,5,6])
运行结果:
(1,2,3,4,5,6)
# 4 使用函数
list1 = [1,1,2,3]
fun1(*list1)
运行结果:
(1,1,2,3)
2.关键字参数(遵循变量命名规则)
-
函数自动将结果包装成了字典,关键字必须为字符串,混合传参时放最后
# 定义函数
def fun1(**args):
print(args)
# 1 使用函数
fun1(a=1,b=2,c=3)
运行结果:
{'a':1,'b':2,'c':3}
# 2 使用函数
fun1(**{'a':1,'b':2,'c':3})
运行结果:
{'a':1,'b':2,'c':3}
(五)参数混合使用
-
关键字必须放最后(指定参数)
例:必备参数+默认参数
-
默认参数必须放在必备参数后,根据定义顺序,确保必备参数只能拿到一个值
# 定义函数
def fun1(a,b=1):
print(a,b)
# 1 使用函数
fun(1,b=2)
运行结果:
1 2
# 2 使用函数
fun(a=1,b=2)
运行结果:
1 2
# 3 使用函数
fun(1,2)
运行结果:
1 2
三,常用内置函数
(一)ipython中列出已有的内置函数
dir(__builtint__)
(二)举例使用
a = [1,1,1,2]
len(a)
min(a)
max(a)
a = [123,456,789,987]
b = sorted(a) # 排序a,将结果返回给b,但并不改变a本身的顺序,sorted有返回值,sort没有
c = list(reversed(a)) # 反序a,将结果返回给b,但并不改变a本身的顺序
d = sum(a) # 求和a内所有元素,将值反给d
x = 100
bin(x) # 转为二进制
oct(x) # 转为八进制
hex(x) #转为十六进制
chr(x) # ascii 转字符
ord('a') # 字符转 ascii
(三)内置高级函数举例使用
1,enumerate(枚举 )
-
自动依此添加一个显示的索引
help(enumerate) # 查看使用
# 例1
#简单使用,返回索引(可默认索引初始值)
a = [123,456,789,987]
b = list(enumerate(a))
运行结果:
b = [(1,123),(2,456),(3,789),(4,987)]
# 例2
##简单使用,可默认索引初始值
c = list(enumerate(a,2))
运行结果:
c = [(2,123),(3,456),(4,789),(5,987)]
# 例3
# 获取列表坐标的方法
for index,value in enumerate(a):
if value == 456:
print(index)
2,eval ,exec
-
1,取出字符串内容,并将结果变为表达式执行出来
-
2,eval不可运行赋值语句, exec,可运行赋值语句
#例1
eval('22+55')
运行结果:
55
#例2
exec('a=1')
运行结果:
1
3, lambda(匿名函数)
-
只能使用一次,简单逻辑
help (lambda) #查看使用
#定义函数
g = lambda x:x+1 #赋值给g,保存下来
#相当于:
def fun(x):
return(x+1)
4, filter(过滤函数)
-
参数1:一个函数,参数2:可以是具体值,,给定一个过滤函数,过滤可迭代对象。
help (filter) #查看使用
# 例1
def guolv(a):
return a>1
b = list(filter(guolv,[1,2,3]))
运行结果
[2,3]
# 例2
b = list(filter(lambda x:x>1, [1,2,3]))
运行结果
[2,3]
# 例3
def myfilter num():
if num>5:
return True
else:
return False
a = [1,2,3,4,5,6,7,8]
b = filter(myfilter,a)
b = list(b)
运行结果:
b = [6,7,8]
5,map(加工)
help (map) #查看使用
# 例1
a = [1,2,3,4,5,6,7,8]
def mymap(num):
return num*10
b = list(map(mymap,a))
运行结果:
b = [10,20,30,40,50,60,70,80]
# 例2
b = list(map(lambda x:x>1, [1,2,3]))
运行结果
[False,True,True]
# 例3
b = list(map(lambda x:x+1, [1,2,3]))
运行结果
[2,3,4]
# 例4
b = list(map(str, [1,2,3])) #不可以map列表
运行结果
['1','2','3']
6,zip(配对)
help (zip) #查看使用
# 例1
# zip(a,b)
a = ['a','b','c','d','e','f']
b = [1,2,3,4,5,6]
c = list(zip(a,b))
运行结果:
c= [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6)]
函数作用域和匿名函数
一、匿名函数
(一) lambda
-
引入
此方式需要自定义my_filter 方法,不够简洁,工作量大
def my_filter(x):
if x > 100:
return True
else:
return False
mylist = [200,55,12000,11]
print(list(filter(my_filter,mylist)))
# 运行结果:[200, 12000]
-
改进
mylist = [200,55,12000,11]
a = list(filter(lambda x : x > 100 , mylist))
print(a)
运行结果:[200, 12000]
- ##### 技巧,保留lambda ```python fun1 = lambda x:x*10 print(fun1(25)) # 运行结果:250
-
小结
lambda x : x * 100
等效为:
def fun1(x):
return x * 100
只是fun1这个函数名被省略了
二、函数作用域
(一)global
##### 演示 ```python my_num = 520 #声明为全局变量 def myfunc(): my_num = 250 #声明局部变量并赋值 print(my_num) #调用的是局部变量 myfunc() print(my_num) #调用的是函数外部变量 运行结果: 250 520
-
全局变量
my_num = 520 #声明为全局部变量
def myfunc():
global my_num #声明当前调用的是全局变量
my_num = 250 #全局变量赋值
print(my_num)
myfunc() print(my_num) #调用的全局变量
运行结果:
250 250
#### (二)nonlocal,调用上层函数的变量
演示
def myfunc(): my_num = 250 # 声明myfunc的局部变量 def inside_func(): my_num = 520 # 声明inside_func函数的局部变量 print(my_num) inside_func() print(my_num)
myfunc() myfunc()
运行结果:
520 250
- ##### 上层函数变量的调用 ```python def myfunc(): my_num = 250 # 声明myfunc函数的局部变量 def inside_func(): nonlocal my_num # 声明为上层函数的变量 my_num = 520 # 上层函数变量重新赋值 print(my_num) inside_func() print(my_num) myfunc() # 运行结果: 520 520
三,闭包(嵌套函数)
(一)引入,调用内层函数的方法
def fun_A():
def fun_B():
print('我是内层函数fun_B')
return fun_B # 将内层函数返回(此处理解为返回内层函数的地址)
resualt = fun_A() # 接收内层函数(resualt接收内层函数的地址)
resualt() # 调用内层函数(此处resualt为一个地址变量,保存的内容为内层 函数的地址,)
# 运行结果:
我是内层函数fun_B
(二)闭包应用之二,函数选择
def fun_A(num):
def fun_dec(x,y):
return x-y
def fun_plus(x,y):
return x+y
if num == '-':
return fun_dec
elif num == '+':
return fun_plus
else:
return None
resualt = fun_A('+')
print(resualt(3,2))
resualt = fun_A('-')
print(resualt(3,2))
# 运行结果:
5
1
四,回调函数
def fun1():
print('第一个函数')
def fun2(a):
a() # 调用fun1, 把fun1当成一个参数
print('第二个函数')
fun2(fun1)
# 运行结果
第一个函数
第二个函数
五,递归函数(调用自己,少用)
-
算阶乘 n!
优点,代码简洁
-
缺点,当递归太多次时容易造成栈溢出,代码不易读
def fun_A(n):
if n == 1:
return 1
return n*fun_A(n-1)
print(fun_A(5))
-
类定义、属性和初始化
-
上节课作业解答
mytuple = ('nanbei', 18, 198)
mydict = {'name': 'juhao', 'age': 16, 'height': '188'}
def exchange1(a, b):
return dict(zip(a.keys(), b)), tuple(a.values())
mydict, mytuple = exchange1(mydict, mytuple)
print(mydict, mytuple)
# 运行结果:
{'age': 'nanbei', 'name': 18, 'height': 198} (16, 'juhao', '188')
一,类定义
(一)简单增加类成员变量
class Person: # 类的定义
var1 = '呵呵' # 直接封装在类中的变量
Person.var2 = '哈哈' # 后来封装在类中的变量
print(Person.var1)
print(Person.var2)
# 运行结果:
呵呵
哈哈
# 可以看到,在类外部为Person类新增了var2成员变量。
(二)类的实例化
class Person:
var1 = '呵呵'
p1 = Person() # 实例化
p2 = Person()
p1.var1 = 'p1 呵呵' # 用p1直接访问var1
p2.var1 = 'p2 呵呵'
print(p1.var1) # 示例中也可看到类中封装的变量
print(p2.var1)
print(Person.var1)
# 运行结果:
p1 呵呵
p2 呵呵
呵呵
# 示例属性可以访问类变量,类变量不能访问实例变量
(三)类的变量,
-
公有变量,形意私有变量(_age),强制私有变量(__height)
class Person:
eye = 2
_age = 18 # 私有变量,外部不要访问,强制用也可以用
__height = 188 # 强制成为私有变量,编译器不允许外部访问
print(Person._age) # 可以运行,但不建议
print(Person.__height) # 报错
二,类的方法
-
类方法,实例方法
# 例1
class Person:
def eat(): # 类方法定义
print('I am eating!')
Person.eat() # 直接调用类方法
# 运行结果:
I am eating!
# 此时:
p = Person()
p.eat() # 报错
# 例2
class Person:
def eat(self): # 实例方法定义
print('%s正在吃饭。。。' % self.name)
p1 = Person()
p1.name = '同学A'
p1.eat() # 调用实例方法
p2 = Person()
p2.name = '同学B'
p2.eat()
# 运行结果
同学A正在吃饭。。。
同学B正在吃饭。。。
# 此时:
Person.eat() # 报错,Person中没有eat属性
-
类方法
eat()
,实例方法eat(self)
-
在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,定义类实例方法时必须包含参数 self, 且为第一个参数,self 代表的是类的实例。
# 例3
class Person:
def eat(self): # 实例方法定义,self 为实例本身
print('%s正在吃饭。。。' % self.name)
print(id(self))
p1 = Person()
p1.name = '同学A'
p1.eat() # 调用实例方法
print(id(p1))
# 运行结果:
同学A正在吃饭。。。
3072556364
3072556364
可见,self 与 p1
内存地址是同一个
三,初始化和析构
(一)类的专有方法(目前无须理解):
方法 | 作用 |
---|---|
__init__ | 构造函数,在生成对象时调用 |
__del__ | 析构函数,释放对象时使用 |
__repr__ | 打印,转换 |
__setitem__ | 按照索引赋值 |
__getitem__ | 按照索引获取值 |
__len__ | 获得长度 |
__cmp__ | 比较运算 |
__call__ | 函数调用 |
__add__ | 加运算 |
__sub__ | 减运算 |
__mul__ | 乘运算 |
__div__ | 除运算 |
__mod__ | 求余运算 |
__pow__ | 乘方 |
(二)魔术方法: __init__(self)
class Person(object):
def __init__(self, name, age, height):
self.name = name
self.age = age
self.height = height
def eat(self):
print('%s正在吃饭...' % self.name)
p1 = Person('同学A', 18, 188)
p1.eat()
print(p1.name)
print(p1.age)
print(p1.height)
# 运行结果:
同学A正在吃饭...
同学A
18
188
-
运行
p1 = Person('同学A', 18, 188)
过程:
注释 | 过程 |
---|---|
实例化,产生一个类的实例 | p1 = Person('同学A', 18, 188) |
python自动调用 实例.__init__(参数) | p1.__init__('同学A', 18, 188) |
转换为 类.__init__(实例,参数) | Person.__init__(p1,'同学A', 18, 188) |
四,总结
术语 | 定义 |
---|---|
类(Class) | 例如上述 Class Person。用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。 |
类变量 | 类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。 |
数据成员 | 类变量或者实例变量用于处理类及其实例对象的相关的数据。 |
方法重写 | 如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。 |
实例变量 | 定义在方法中的变量,只作用于当前实例的类。 |
继承 | 即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。 |
实例化 | 创建一个类的实例,类的具体对象。 |
方法 | 类中定义的函数。 |
对象 | 通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。 |
继承、多继承、魔术方法
-
上节课作业解答
class Rectangle(object):
def __init__(self, width, length):
self.width = width
self.length = length
# 两个方法之间留一个空行
# 运算符后面跟一个空格
def get_area(self):
return self.width * self.length
#类之间空两行
rect1 = Rectangle(10, 20)
rect1.get_area()
print(rect1.get_area())
# 运行结果:
200
一,继承
(一)继承的使用方式
class Rectangle(object): #父类/基类
def __init__(self, width, length):
self.width = width
self.length = length
def get_area(self):
return self.width * self.length
class Square(Rectangle): #继承
pass
square = Square(50,50)
print(square.get_area())
# 运行结果:
2500
# 此处Square类继承了Rectangle类 Square拥有了Rectangle里的所有方法及其属性
# 重用代码,方便代码的管理
(二)继承的搜索
class Rectangle(object):
def __init__(self, width, length): # 实例化传参时 将初始化参数
self.width = width
self.length = length
def get_area(self):
return self.width * self.length
class Square(Rectangle):
def __init__(self, width, length):
if width == length:
Rectangle.__init__(self, width, length) # 此处调用了父方法
else:
print('长度和宽度不相等,不能成为正方形')
square = Square(25, 25)
square.get_area()
square1 = Square(25, 22)
# 运行结果
长度和宽度不相等,不能成为正方形
(三)Object,_ _bass__ 特殊属性
-
Object最顶层的类,类的老祖宗
-
_ _bass__ 特殊属性,反回的是父类
二,多继承
-
一个子类可以继承多个父类是多继承
-
一层层继承下去是多重继承
# 例1
class Base(object):
def play(self):
print('Base is playing!')
class A(Base): # 继承Base
def play(self): # 自动覆盖父类的此方法
print('A is playing')
def sing(self):
print('B is singing')
class B(Base): # 继承Base
def play(self):
print('B is playing')
def learn(self):
print('B is learning')
class C(A, B): # 继承A,B
pass
c = C()
c.sing()
c.learn()
c.play()
# 运行结果:
B is singing
B is learning
A is playing
# 说明 :
# 1,C类继承了A类及B类的属性及方法
# 2,对于A与B相同的方法play,优先继承最左边的那个
-
继承多个父类时,若想指定继承哪一个类的方法,可以重写的方式达到效果
#例2,
class C(A, B): # 继承A,B
def play(self): #覆盖父类
B.play(self) # 指定继承B类内的play方法
-
super()
# 例3
class Base(object):
def play(self):
print('Base is playing!')
class A(Base): # 继承Base
def play(self): # 自动覆盖父类的此方法
super().play() # 调用父类方法
print('A is playing!')
a = A()
a.play()
# 运行结果:
Base is playing!
A is playing!
#说明:
super()可自动找到父类方法
# 例4,在例1中更改如下代码
class C(A, B): # 继承A,B
def play(self):
super().play()
print('C is playing')
c = C()
c.play()
# 运行结果:
A is playing
B is learning
C is playing
-
类.mro() 查看继承顺序
print(C.mro())
# 运行结果:
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.Base'>, <class 'object'>]
-
super()深层次用法
# 例5
class Base(object):
def play(self):
print('Base is playing!')
class A(Base): # 继承Base
def play(self): # 自动覆盖父类的此方法
super().play()
print('A is playing')
class B(Base): # 继承Base
def play(self):
super().play()
print('B is playing')
class C(A, B): # 继承A,B
def play(self):
super().play()
print('C is playing')
c = C()
c.play()
print(C.mro())
# 运行结果:
Base is playing!
B is playing
A is playing
C is playing
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.Base'>, <class 'object'>]
# 说明 循根溯源执行
由mro()可以看出,C的继承顺序为A,B,Base,object
c在执行play()方法时,也是按此顺序执行
1,c.play()遇到super().play(),此时压栈并溯源到A.play()
2,在A.play()遇到super().play(),此时压栈并继续溯源到B.play()
3,在B.play()遇到super().play(),此时压栈并继续溯源到Base.play()
4,在Base.play()遇到print,此时执行打印: 1# Base is playing!
5,Base.play()执行结束,此时出栈到B.play(),在此时B中的super().paly()已经执行完成,
紧接着遇到print,此时执行打印: 2# B is playing
6,B.play()执行结束,此时继续出栈到A.play(),在此时A中的super().paly()已经执行完成,
紧接着遇到print,此时执行打印: 3# A is playing
7,A.play()执行结束,此时继续出栈到C.play(),在此时C中的super().paly()已经执行完成,
紧接着遇到print,此时执行打印: 4# C is playing
8,运行结束。输出如上结果。
三,魔术方法(下节课内容)
(一)类的专有方法(目前无须理解):
方法 | 作用 |
---|---|
__init__ | 构造函数,在生成对象时调用 |
__del__ | 析构函数,释放对象时使用 |
__repr__ | 打印,转换 |
__setitem__ | 按照索引赋值 |
__getitem__ | 按照索引获取值 |
__len__ | 获得长度 |
__cmp__ | 比较运算 |
__call__ | 函数调用 |
__add__ | 加运算 |
__sub__ | 减运算 |
__mul__ | 乘运算 |
__div__ | 除运算 |
__mod__ | 求余运算 |
__pow__ | 乘方 |
(二)魔术方法: __init__(self)
class Person(object):
def __init__(self, name, age, height):
self.name = name
self.age = age
self.height = height
def eat(self):
print('%s正在吃饭...' % self.name)
p1 = Person('同学A', 18, 188)
p1.eat()
print(p1.name)
print(p1.age)
print(p1.height)
# 运行结果:
同学A正在吃饭...
同学A
18
188
-
运行
p1 = Person('同学A', 18, 188)
过程:
注释 | 过程 |
---|---|
实例化,产生一个类的实例 | p1 = Person('同学A', 18, 188) |
python自动调用 实例.__init__(参数) | p1.__init__('同学A', 18, 188) |
转换为 类.__init__(实例,参数) | Person.__init__(p1,'同学A', 18, 188) |
new方法和单例、定制访问函数、装饰器
-
上节课作业解答
# 通过多重继承方法,分别定义出动物,人类,和和荷兰人三种类
class Animal(object):
def __init__(self, name):
self.name = name
def eat(self):
print('%s正在吃东西' % self.name)
def breath(self):
print('%s正在呼吸' % self.name)
class Person(Animal):
def __init__(self, name, money):
super().__init__(name)
self.money = money
def speak(self):
print('%s说他有%s人民币' % (self.name, self.money))
class Fulan(Person):
def eat(self):
print('弗兰人%s不仅爱吃辣,而且爱吃槟榔' % self.name)
def speak(self):
print('福兰人%s正在blablabla讲弗兰话。' % self.name)
juhao = Fulan('句号', 23)
juhao.breath()
juhao.eat()
juhao.speak()
#拼接一个Spiderman
class Spider(Animal):
def climb(self):
print('%s正在攀岩' % self.name)
def tusi(self):
print('%s正在吐丝' % self.name)
class Spiderman(Person, Spider):
pass
Spiderman = Spiderman('Spiderman', 10)
Spiderman.tusi()
Spiderman.climb()
Spiderman.eat()
Spiderman.breath()
#说明:
1. 调用父类的两种方法:
Animal.__init__(self.name)
super().__init__(name)
2. 不能直接调用__init__,且__init__只能有一个
-
以上运行结果
句号正在呼吸
弗兰人句号不仅爱吃辣,而且爱吃槟榔
福兰人句号正在blablabla讲弗兰话。
Spiderman正在吐丝
Spiderman正在攀岩
Spiderman正在吃东西
Spiderman正在呼吸
一、魔术方法补充
所有的函数都是类(对象)
魔术方法示例:(__方法__)
(一) 引入
a = 'hahaha'
b = '12'
print(b + a)
# 等效于
print(b.__add__(a))
# 运行结果
# 12hahaha
# 12hahaha
(二) 魔术方法在类中的使用
-
示例
__add__
# 添加其他属性
# 魔术方法在类中的使用
class Rectangle(object):
def __init__(self, length, width):
self.length = length
self.width = width
def get_area(self):
return self.length * self.width
def __add__(self, other):
add_length = self.length + other.length
add_width = self.width + other.width
return add_length, add_width
-
示例
__str__
__repr__
str(面向使用者,提供简洁有用信息)
repr(面向开发者,提供接近创建时的信息,让开发者可以通过复制粘贴来重建对象)
直接在交互界面中,直接返回值和print()所使用的(str和repr)魔术方法不同
# str和repr原理
# 例 1
def __str__(self):
return 'length is %s, width is %s' % (self.length, self.width)
def __repr__(self):
return '长是%s,宽是%s'% (self.length, self.width)
def __call__(self, *args, **kwargs):
print('我正在被调用')
rec1 = Rectangle(10, 20)
rec2 = Rectangle(30, 40)
rec1()
print(rec1 + rec2)
print(str(rec1)) # (如果不写rec1会返回函数体<……>)
print(repr(rec1)) # (如果不写rec1会返回函数体<……>)
# 运行结果
我正在被调用
(40, 60)
length is 10, width is 20
长是10,宽是20
# 注: 直接在交互界面中,直接返回值和print()使用的(str和repr)魔术方法不同
# 例 2
a = '1,2,3'
a
'1,2,3'
print(a)
1,2,3
# 说明:
函数可以直接调用,但是类必须要使用call魔术方法才可以直接调用
(三) 简单魔术方法(了解)
__class__ | 查看类名 |
---|---|
__base__ | 查看继承的父类 |
__mro__ | 追根溯源到object,super是基于mro实现的 |
__bases__ | 查看继承的全部父类 |
__dict__ | 查看全部属性,返回属性和属性值键值对形式 |
__doc__ | 查看对象文档,即类中的注释(用引号注释的部分)(注释不能被继承) |
__dir__ | 查看全部属性和方法(等效于dir) |
二、new方法和单例
在初始化函数init之前执行,创建实例
# __new__
a = Rectangle.__new__()
Rectangle.__init__(a)
# 单例模式(节省内存)
class Esrth(object):
def __new__(cls, *args, **kwargs): # 新建实例
if not hasattr(cls,'instance'): # 如果所定义的函数没有instance属性
cls.instance = super().__new__(cls) # 那么就新建一个instance属性,并赋值给父类,此时instance为Esrth的一个实例(或属性)
return cls.instance
def __init__(self): # 对实例的初始化
self.name = '单例'
a = Esrth()
print(id(a))
b = Esrth()
print(id(b)) # 把e覆盖了
#运行结果
3072614988
3072614988
# 说明:
给Earth类新建一个类属性,名叫instance,给这个instance赋值,赋的值为Earth类的一个实例。
最终运行结果就是,首次新建Earth实例时,此时没有实例,则给它新建一个实例,名字叫instance,并将这个实例变成Earth类的一个属性,保存起来。以后再新建Earth实例时,Earth发现自身已经有了一个instance实例,此时将instance拿出来,所以,不管Earth新建多个实例,这个实例都是instance,也就是单例。
1. 在以上例子中可以看见两个实例的id其实是相同的,意味着这两个实例其实引用的是同一个实例,(只占一个内存)是一个实例的不同名字(使用单例创建多个对象 对象内存指向同一个地址 节省内存 但是会跟着值的改变而改变 普通实例不会)
2. 其中self代表实例本身,cls代表类本身hasattr判断类中有没有('')参数
3. 如果没有就调用object中new方法
三、定制访问函数
(一) 常见方法
作用 | 方法 | 返回 |
---|---|---|
查 | hasattr(re,'length') | 返回bool值 |
getattr(re,'length') | 返回属性值 | |
b.__getattribute__('length') | 返回全部属性值 | |
改 | setattr(b,'length',6) | |
b.__setattr__('length',5) | ||
增 | b.aaa = 1 | |
setattr(b,'leg',2) | ||
b.__setattr__('leg',3) | ||
删 | delattr(b,'leg') | |
b.__delattr__('leg') | ||
del b |
注:print(hasattr(实例rec1,属性'length'))等效于print(rec1.__hasattr__('name'))
(二) 举例
# 定制属性访问
# 例 __getattr__
re = Rectangle(3,4)
def __getattr__(self,item):
print('no attribute')
# 当属性不存在时,若定义了此方法则调用此方法,若存在则返回原值
(三) 了解__getattribute__
b.__getattribute__('length')
# 正常调用返回属性值,属性值不存在,调用__getattr__未定义时会报错
四、装饰器
(一) 引入
def eat():
return '小明在吃东西'
def boom():
return eat() + '并且爆炸了'
print(boom())
#等效于
def boom(func):
return func() + '并且爆炸了'
xiaoming = boom(eat)
print(xiaoming)
# 运行结果
小明在吃东西并且爆炸了
小明在吃东西并且爆炸了
(二) 改善
可以看到输出时方式不一样,可以修改为以下操作
# 例 1
def boom(func):
def new_func():
return func() + '并且爆炸了'
return new_func
xiaoming = boom(eat)
print(xiaoming())
#运行结果
小明在吃东西并且爆炸了
# 例 2
def eat2(name):
return '小明和%s在吃东西' % name
def boom2(func2):
def new_func2(name):
return func2(name) + '并且爆炸了'
return new_func2
eat2 = boom2(eat2)
print(eat2('小红'))
#运行结果
小明和小红在吃东西并且爆炸了
(四) 装饰器
def boom3(func3):
def new_func3(name):
return func3(name) + '并且爆炸了'
return new_func3
(五) 其他装饰器
class Rectangle:
def __init__(self, length, width):
self.length = length
self.width = width
def area(self):
areas = self.length * self.width
return areas
# 像访问属性一样
(六) 装饰器参考
from datetime import datetime
def run_time(func):
def new_func(*args,**kwargs):
start_time = datetime.now()
print('程序开始时间:%s' % start_time)
func(*args, **kwargs)
end_time = datetime.now()
print('程序结束时间:%s' % end_time)
print('程序总共执行时间:%s' % (end_time - start_time))
return new_func()
print(datetime.now())
# 运行结果
2018-04-13 17:10:39.332348
第14节 文件
解答课内容补充
1,Linux命令
Linux命令 | 作用 | 示例(不对应首列命令) | 作用 |
---|---|---|---|
find | 查找 | 格式:find [-path] -options | |
path | 要查找的目录,默认当前目录 | ||
option: | |||
-name | 按文件名的某种规则查找 | find ./ -name '*.py' -print | 查找当前目录下所有后缀为py的文件 |
-type | 按文件类型查找 f普通文件 l符号连接 d目录 | find ./ ! -name '*.py' | 查找当前目录下所有后缀不为py的文件 |
-size | 按文件大小查找 | find -size +6k | 查找大于6k的文件,不写的时候就是等于 |
-exec<执行指令> | 假设find的回传值为True就执行该指令 | find ./ -name '*.py' -exec rm -rf {} \; | 删除当前目录下所有py文件(慎用!) |
假设find的回传值为True,就将文件或目录名称列出到标准输出 |
2,描述符
这类里面实例化另一个类,对这个示例做访问时,可用__get__ __set__ __delete__方法
class MyClass(object):
def __get__(self, instance, owner):
return '超哥666'
def __set__(self, instance, value):
print('this is %s' % value)
def __delete__(self, instance):
print('南北666')
class Control(object):
attr = MyClass() # attr是一个实例
c = Control()
print(c.attr) #使用c.attr的时候会调用MyClass类的__get__方法
c.attr = 10
del c.attr
# 运行结果
超哥666
this is 10
南北666
3,作业解答
-
思路
# 测试type和isinstance两个函数,哪个速度更快
# 思路:
1,定义两个函数
2,加功能(定义run_time函数参数传入func,闭包函数count(为加装饰器),写好装饰器的框架return内层 return count外层)
3,导入datetime模块
4,统计开始时间,调用函数func并用temp接收,内层return出temp,再统计结束时间
5,print出运行时间
6,加上函数本身装饰器(注:函数装饰器不能加到类上)
-
过程
from datetime import datetime
def run_time(func):
def count(*args):
start_time = datetime.now()
temp = func(*args)
end_time = datetime.now()
print('程序的运行时间是:%s' % (end_time - start_time))
return temp
return count #装饰器要装饰到别的函数上不能直接调用
一,文件基本操作
1,打开文件
path = 'test.txt' # 文件与当前py文件处于同一目录
path = r'/home/pyvip/py_case/text.txt' # 文件与当前py文件处于同一目录(从其他文件夹下访问其他文件要从根目录下写)
file = open(path, 'r') # 打开文件 参数r为读取
file.read() # 读取文件返回值为文件内容
2,写入文件
file.open('test.txt','w') # 打开文件 参数w为可写,但写完会覆盖原有内容
file.write('今天天气不错') # 写入
file.close() # 关闭文件,此时文件内容为:今天天气不错
file.open('test.txt','a') # 打开文件 参数a为在文件后添加内容
file.write('今天天气不错2') # 写入
file.writelines(['1','2','3']) # 写入,可传入[]拼接到一起 类似join
file.flush() # 保存文件
3,读取与关闭
file.read() # 读取全部内容
file.readline() # 读取一行
file.readlines() # 一行保存为一个元素,组成一个列表
file.close()
# 注文件open()后,必须close()
4,查看
file=open('test.txt','r')
file.tell() # 返回此时光标的位置(查看指针)
file.readline() # 读取一行
file.seek(0) # 将文件光标移动到起始位置
file.seek(70) # 将文件光标移动到70的位置,
5,小结
模式 | 描述 |
---|---|
r | 以只读方式打开文件,文件指针默认放在文件开头 |
rb | 以二进制格式打开一个文件用于只读,文件指针默认放在文件开头,一般用于非文本文件(如图片等) |
r+ | 以二进制格式打开一个文件用于读写,文件指针默认放在文件开头 |
rb+ | 打开一个文件用于读写,文件指针默认放在文件开头,一般用于非文本文件(如图片等) |
w | 打开一个文件只用于写入,如果该文件已存在则将其覆盖,如果不存在,创建新文件 |
wb | 以二进制格式打开一个文件用于只读,如果该文件已存在则将其覆盖,如果不存在,创建新文件,一般用于非文本文件(如图片等) |
w+ | 打开一个文件用于读写,如果该文件已存在则将其覆盖,如果不存在,创建新文件 |
wb+ | 以二进制格式打开一个文件用于读写,如果该文件已存在则将其覆盖,如果不存在,创建新文件,一般用于非文本文件(如图片等) |
a | 打开一个文件用于追加,如果文件已存在,文件指针会放在文件结尾(也就是说,新的内容将会被写到已有内容之后)如果不存在,创建新文件进行写入 |
ab | 以二进制格式打开一个文件用于追加,如果文件已存在,文件指针会放在文件结尾(也就是说,新的内容将会被写到已有内容之后)如果不存在,创建新文件进行写入 |
a+ | 打开一个文件用于读写,如果文件已存在,文件指针会放在文件结尾,文件打开时会是追加模式,如果不存在,创建新文件用于读写 |
ab+ | 以二进制格式打开一个文件用于追加,如果文件已存在,文件指针会放在文件结尾,如果不存在,创建新文件用于读写 |
二,上下文管理
1,自动关闭文件 (with的用法)
-
openxls (python管理表格的模块openxls更好)
with open('test.txt','r') as file:
print(file.read())
# 例:
from datetime import datetime
class RunTime(object):
def __enter__(self):
self.start_time = datetime.now()
print(self.start_time)
return self.start_time
def __exit__(self, exc_type, exc_val, exc_tb):
self.end_time = datetime.now()
print(self.end_time)
print('运行时间为: %s' % (self.end_time - self.start_time))
run = RunTime()
with run as a:
for i in range(200):
type('hello')
# 运行结果:
2018-04-18 01:47:34.042769
2018-04-18 01:47:34.043882
运行时间为: 0:00:00.001113
# 通过这两个方法可以方便的实现上下文管理
with 会把 __enter__的返回值赋值给as后的变量
以后敲代码用with,避免直接使用open()
三,IO流
引入
文件可以持久存储,但是现在类似于临时的一些文件,不需要持久存储,如一些临时的二维码,这个不需要持久存储,但是却需要短时间内大量读取,这时候还是只能保存在文件里吗?
1,StringIO
StringIO 在内存中如同打开文件一样操作字符串,因此也有文件的很多方法,当创建StringIO调用close()方法是,在内存中的数据会被丢失
-
创建IO操作
import io
myio = io.StringIO()
myio.write('今天天气不好')
myio.getvalue() # 读取
# 此操作在内存中,未在硬盘里
-
写入
import io
myio = io.StringIO()
myio.write('今天天气不好')
myio.getvalue()
# 此操作在内存中,未在硬盘里
2,BytesIO
-
操作二进制(一般用于处理图片)
import io
my_byte_io = io.BytesIO()
my_byte_io.write(b'hello')
print(my_byte_io.getvalue())
3,OS 操作系统交互
os 模块提供python和操作系统交互的接口
-
直接调用系统命令
import os
os.system('ls')
os.system('cat test.txt')
-
通用路径的操作
import os
os.path
os.path.join('pyvip','hch','hello') # 拼接路径
os.mkdir('py_case2')
os.rename('py_case2','py_case_del') # 重命名
4,shutil
-
移动文件
import shutil
shutil.move('test.txt','tanzhou')# 将文件test.txt移动到tanzhou文件夹内
-
复制文件
shutil.copytree
-
删除文件
shutil.rmtree
第15节 异常
作业解答
# 根据课堂上给出的上下文管理器,判断IO操作和文件操作那个速度快
from datetime import datetime
import io
class RunTime(object):
def __enter__(self):
self.start_time = datetime.now()
print(self.start_time)
return self.start_time
def __exit__(self, exc_type, exc_val, exc_tb):
self.end_time = datetime.now()
print(self.end_time)
print('运行时间为: %s' % (self.end_time - self.start_time))
sio = io.StringIO()
sio.write('今天天气真好')
with RunTime() as a:
with open('duqusucai.py', 'r') as file:
print(file.read())
with RunTime() as b:
print(sio.getvalue())
# 运行结果:
2018-04-18 02:58:20.221762
今天天气真好
2018-04-18 02:58:20.228967
运行时间为: 0:00:00.007205
2018-04-18 02:58:20.229365
今天天气真好
2018-04-18 02:58:20.229521
运行时间为: 0:00:00.000156
一,认识异常
-
Python的异常结构
python中所有的异常都是继承自BaseException,分为四大类:
类型 | 描述 |
---|---|
SystemExit | python退出异常 |
Keyboardlnterrupt | 键盘打断(ctrl + c) |
GeneratorExit | 生成器退出 |
Exception | 普通异常 |
二,异常处理
-
例 1
try:
with open('meiyouzhegewenjian.txt', 'r') as f:
f.read()
except: # except错误用法
print('没有找到该文件')
# 当try中的代码出现异常时,运行except. 若没错就运行try,except后可捕捉指定种类错误(例:except FilNotFoundError)
-
例 2
try:
raise TypeError('这是一个类型错误')
except Exception as a: # except正确用法
print(a)
# raise 为主动抛出异常
-
例 3 (控制类型)
def myfunc(num):
if type(num) != int:
raise TypeError('不是数字')
return num * 10
print(myfunc('hello'))
# 若传入不为int会报错,反之则会正常运行
-
例 4
def myfunc(num):
if type(num) != int:
raise TypeError('不是数字')
return num * 10
try:
print(myfunc('hello'))
except TypeError:
print('类型错误')
else:
print('没有错误')
finally:
print('不管怎样,finally都会执行')
# 运行结果:
类型错误
不管怎样,finally都会执行
-
例 5 (当不确定有没有这个属性时)
dic = {'name': 'a', 'age': 18}
try:
print(dic['age'])
except KeyError:
print('字典里没有这个值')
# 运行结果:
18
# 若查找值不存在会报错,反之则会正常运行
三,断言(类似raise)
if not False:
raise Exception('条件不满足')
等效于:
assert True # 不抛出异常
assert False # 抛出异常
-
例
def myfunc(num):
if type(num) != int:
raise TypeError('不是数字')
return num * 10
print(myfunc('hello'))
# 若传入不为int会报错,反之则会正常运行
四,自行定义异常类型 (控制类型)
class NameMustBeLuckError(Exception):
pass
def myfunc(name):
if name != 'luck':
raise NameMustBeLuckError('The name must be luck!')
try:
print(myfunc('juhao'))
except Exception as a:
print(a)
# 运行结果:
The name must be luck!
第16节 迭代器,生成器
作业解答
import os
if not os.path.exists('my_tesr.txt'): # 判断文件是否存在
file = open('my_test.txt', 'w+', encoding='utf-8')
try:
my_dict = {'name': 'xiaojiu'}
file.write(my_dict['name'])
except Exception as e:
print(e)
finally:
file.close()
print('文件正常关闭')
# 文件存在则不会运行try
一,迭代器
1,迭代对象与迭代器
-
依次从数据结构中取出东西的过程
-
可以用更加低级的while实现,但比较麻烦,如:
# 例1
mylist=[1,2,3,4,5,6]
index = 0
while index < 6:
print(mylist[index])
index += 1
# 说明:需自己控制下标并获取对应元素
# 例2,改进
for i in mylist:
print(i)
-
可迭代对象与迭代器的区别:for 迭代变量 in 可迭代对象
-
每一次循环都会自动让 ‘迭代变量’ 指向 ‘下一个元素’
-
迭代器 = iter(可迭代对象)
-
下个值 = next(迭代器)
mylist = [1,2,3,4]
myiter = iter(mylist) #此时mylist即为可迭代对象,转化为迭代器
a = next(myiter) #此时myiter为迭代器(依此取值)
#此时a的值为1
b = next(myiter) #此时b的值为2
c = next(myiter) #此时c的值为3
d = next(myiter) #此时d的值为4
e = next(myiter) #此时报错,原因,迭代器已结束
2,for实现原理
itr = iter(the_list) # 转化为迭代器
try:
while True:
var = next(itr)
print(var)
except StopIteration:
pass
3,归纳总结
-
只需要了解:for...in...的运行机制
-
必须掌握:iter,next两个内置函数的使用
-
能够区分:可迭代对象与迭代器
-
可迭代对象里面有
__iter__
, -
可迭代器里面有
__iter__
和__next__
二,生成器
1,自己实现一个可迭代对象
-
在自定义的类中,要实现
__iter__
魔术方法,该魔术方法,必须返回一个迭代器(也需要自己实现)
class Mylist(object):
def __iter__(self): # 自定义__iter__方法
return iter([1, 2, 3, 4, 5]) # 并且此方法返回了一个迭代器
my_list = Mylist() # 此时my_list就是一个可迭代对象
for i in my_list:
print(i)
2,更加优雅的方式生成可迭代对象——>生成器
-
生成器与yield
# 例1 (类似函数逻辑)
def myfunc():
yield 'hello'
yield 'hello'
a = myfunc() #此处 a即为一个迭代器
print(next(a))
print(next(a))
#运行结果
hello
hello
# 例2 (支持暂停与恢复,同时兼顾return的作用)
def myfunc():
print('第一行')
yield 1
print('第二行')
yield 2
print('第三行')
yield 3
print('第四行')
yield 4
a = myfunc()
next(a) #此时打印输出:第一行 next返回1
next(a) #此时打印输出:第二行 next返回2
next(a) #此时打印输出:第三行 next返回3
next(a) #此时打印输出:第四行 next返回4
def cycle(elem, n): #生成器
count = 0
while True:
if count < n:
count += 1
yield elem
else:
break
mycycle = cycle('胖佳', 10)
for i in mycycle:
print(i)
-
生成器,可以很好的优化内存 (因为元素没有放在一起)
def mylist(num):
count = 0
while count<num:
yield count
count += 1
a = mylist(1000000000000000000)
for i in a:
print(a)
-
生成器与迭代器的区别
生成器是python提供的一种非常简便的语法,能让我们自己写出迭代器。生成器是一种特殊的迭代器
三,模块与包
-
导入包
import datetime
import time
import math
-
导入模块
from datatime import datetime
#from 包 import 模块
-
import --->执行导入的文件-->在当前文件里生成一个模块对象
1,导入语法
语法 | 描述 |
---|---|
import .... | 直接导入 |
import ... as... | 导入以后,重新命名 |
form ... import ... | 部分导入模块内部的东西,而不要模块 |
sys.path | 用于存放导入路径的列表,类似于环境变量中的path |
-
例
import datetime as dt
from datetime import datetime as dt
import sys
print(sys.path)
2,包管理(包:包含了很多模块的文件夹。层级导入)
-
在项目里右键新建python package,取名叫my_package
-
此时会在my_package内自动生成
__init__.py
(不加__init__,有可能不会认定my_package为一个包
) -
在my_package内即可新建自己的包及模块
第17节 正则表达式
# 上节课作业
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n += 1
myfib = fib(10)
for i in myfib:
print(i)
def fib2():
a, b = 0, 1
while True:
a, b = b, a + b
yield a
myfib3 = fib2()
for i in myfib3:
if i > 3:
break
print(i)
一,正则表达式
-
正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。
-
能方便的匹配与提取字符串
1,re.findall()
-
从字符串中读取邮箱
#例1
import re
mystr = '32566464@qq.com'
mymail = re.findall(r'^[a-zA-Z0-9]+@[a-zA-Z0-9]+\.com$', mystr)
print(mymail)
# 运行结果
['32566464@qq.com']
分析:
r,转义字符,
#例2 搜索功能
import re
mystr = '冯娅同学:1,正在吃东西,2,吃完东西;3,出门散步'
mymail = re.findall(r'冯娅',mystr )
print(mymail)
# 运行结果
['冯娅', '冯娅']
-
元字符的应用
#例3 搜索功能
import re
mystr = '冯娅同学:1,正在吃东西,2,吃完东西;3,出门散步'
mymail = re.findall(r'[0-9]',mystr )
print(mymail)
# 运行结果
['1', '2', '3']
二,详解元字符
1,通配元字符“.”
# 例1
mystr = '冯娅同学:1,正在吃东西,2,吃完东西;3,出门散步'
mymail = re.findall(r'.',mystr )
print(mymail)
# 运行结果
['冯', '娅', '同', '学', ':', '1', ',', '正', '在', '吃', '东', '西', ',', '2', ',', '吃', '完', '东', '西', ';', '3', ',', '出', '门', '散', '步']
# 例2
mystr = '冯娅同学:1,正在吃东西,2,冯娅吃完东西;3,冯娅出门散步'
mymail = re.findall(r'冯娅..',mystr )
print(mymail)
# 运行结果
['冯娅同学', '冯娅吃完', '冯娅出门']
# 例3
mystr = '冯娅同学:1,正在吃东西,2,冯娅吃完东西;3,冯娅出门散步'
mymail = re.findall(r'..冯娅..',mystr )
print(mymail)
# 运行结果
['2,冯娅吃完', '3,冯娅出门']
2,锚点元字符“^”,"$"
-
可以判断目标匹配字符在行首/行尾
# 例4
mystr = '冯娅同学:1,正在吃东西,2,冯娅吃完东西;3,冯娅出门散步'
mymail = re.findall(r'^冯娅..',mystr )
print(mymail)
# 运行结果
['冯娅同学']
只打印行首
# 例5
mystr = '冯娅同学:1,正在吃东西,2,冯娅吃完东西;3,冯娅出门散步'
mymail = re.findall(r'散步$',mystr )
print(mymail)
# 运行结果
['散步']
只打印行尾
3,单词边界(不属于元字符) “\b”
# 例5
my_str = "hello world i am happy today , happyend"
mymail = re.findall(r'happy',my_str )
print(mymail)
mymail = re.findall(r'\bhappy\b',my_str )
print(mymail)
# 运行结果
['happy', 'happy']
['happy']
三,重复元字符
1,“{“,”}”等符号的用法
# 例1
my_str = "abbbbbbbbbbbbbbbc"
mymail = re.findall(r'ab{15}c',my_str )
print(mymail)
mymail = re.findall(r'ab{10}c',my_str )
print(mymail)
# 运行结果
['abbbbbbbbbbbbbbbc']
[]
# 例2
my_str = "abbbbbbbbbbbbbbbc"
mymail = re.findall(r'ab{2,15}c',my_str )
print(mymail)
mymail = re.findall(r'ab{2,14}c',my_str )
print(mymail)
mymail = re.findall(r'ab{2,16}c',my_str )
print(mymail)
# 运行结果
['abbbbbbbbbbbbbbbc']
[]
['abbbbbbbbbbbbbbbc']
{2,16}表示2个到16个
mymail = re.findall(r'ab{2,}c',my_str )
[0-9]{2,8}表示2到8个,0到9的数
{2,}表示至少为2,多到无穷
{,5}表示最多为5,从0开始
2,贪婪/非贪婪模式
-
贪婪与非贪婪模式影响的是被量词修饰的子表达式的匹配行为,贪婪模式在整个表达式匹配成功的前提下,尽可能多的匹配,而非贪婪模式在整个表达式匹配成功的前提下,尽可能少的匹配。
my_str = "abbbbbbbbbbbbbbbc"
mymail = re.findall(r'ab{3,8}', my_str)#贪婪
print(mymail)
mymail = re.findall(r'ab{3,8}?', my_str)#非贪婪
print(mymail)
# 运行结果
['abbbbbbbb'] #贪婪
['abbb'] #非贪婪
-
贪婪模式(贪婪模式后面加个?为非贪婪模式(尽可能少的匹配字符))
“*”至少0个b
mymail = re.findall(r'ab*c',my_str )
“+”至少1个b
mymail = re.findall(r'ab+c',my_str )
“?” 0次或1次。
my_str = "abc"
my_str2 = "ac"
mymail = re.findall(r'ab?c',my_str )
print(mymail)
mymail = re.findall(r'ab?c',my_str2 )
print(mymail)
# 运行结果
['abc']
['ac']
{N}代表N个
{M,N}代表M~N个
{M,}代表至少M个
.*尽可能多的匹配字符
-
复合使用
# 例3 取出以happy开头的单词
my_str = "hello world i am happy today , happyend ,happynewyear"
mymail = re.findall(r'\bhappy.*?\b',my_str )
print(mymail)
# 运行结果
['happy', 'happyend', 'happynewyear']
3,选择元字符
-
"|"
my_str = "hello world i am happy today , happyend ,happynewyear"
mymail = re.findall(r'he|ha|en',my_str )
print(mymail)
# 运行结果
['he', 'ha', 'ha', 'en', 'ha']
-
"[","]"整个方括号表示1个字符,括号内表示规则
#例1匹配0-9的数字
my_str = "abbc1234569877"
mymail = re.findall(r'[0-9]', my_str)
print(mymail)
# 运行结果
['1', '2', '3', '4', '5', '6']
#例2匹配4个0-9的数字
my_str = "abbc1234567895421"
mymail = re.findall(r'[0-9]{4}', my_str)
print(mymail)
# 运行结果
['1234', '5678', '9542']
#例3匹配有ab的de字符
my_str = "abc abb abd abe"
mymail = re.findall(r'ab[de]', my_str)
print(mymail)
# 运行结果
['abd', 'abe']
# 例4(匹配所有的大小写数字)
my_str = "aBc Abb abd abe 987"
mymail = re.findall(r'A-Za-z0-9', my_str)
print(mymail)
# 运行结果
['a','B','c','A','b','b','a','b','d','a','b','e','9','8','7']
-
[^...]
反向字符类(除此[]以外的所有字符) -
[...N-M...]
范围
4,转义元字符\
例:\b(单词边界)
5,预定义字符类
例:res = re.findall(r'-\w+@\w+.com$', '12345678910@qq.com')
预定义 | 说明 | 对等字符类 |
---|---|---|
\d | 任一数字字符 | [0-9] |
\D | 任一非数字字符 | [^0-9] |
\s | 任一空白符 | [\t\n\x0B\f\r] |
\S | 任意非空白符 | [^\t\n\x0B\f\r] |
\w | 任一字母数字字符 | [a-zA-Z0-9] |
\W | 任一非字母数字字符 | [^a-zA-Z0-9] |
6,括号的应用
-
提取括号内的元素,取出的是一个整体
# 例1
mymail = re.findall(r'<(.*?)>',my_str)
for i in mymail:
print(i)
mymail = re.findall(r'href="(.*?)/>',my_str)
mymail = re.findall(r'rel="(.*?)" href="(.*?)"',my_str)