python基础

 #  有任何侵权问题,请私信我!

第一章

数值类型和序列类型

数值类型

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元组包含了以下内置函数

序号方法及描述实例
1len(tuple)计算元组元素个数。>>> tuple1 = ('Google', 'Runoob', 'Taobao')>>> len(tuple1)3>>>
2max(tuple)返回元组中元素最大值。>>> tuple2 = ('5', '4', '8')>>> max(tuple2)'8'>>>
3min(tuple)返回元组中元素最小值。>>> tuple2 = ('5', '4', '8')>>> min(tuple2)'4'>>>
4tuple(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帮助 
workon1.查看虚拟环境(进入虚拟环境workon py3env) 
deactivate退出虚拟环境(ctrl+c返回) 
source ~/.virtualenvs/py3env/bin/activate2.进入虚拟环境(切换虚拟环境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/
sshssh客户端连接工具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解压缩文件,后缀为.gzgzip 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和监测作用示例
shshell命令语言解释器sh install.sh
bash大多数Linux默认shellbash 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个空格)执行语句1print('a比5大,比10小')
elif :判断语句2:elif a >= 10:
执行语句2执行语句2print('a比10大')
………………
else :判断语句3:else:
执行语句n执行语句nprint('a比5小')

注:
符合条件就不会向下执行
若缩进一样则代表同一个代码块,运行时一起

三目运算

语法结构:b = 值1 if 判断语句 else 值2 (if成立返回值1,不成立返回值2)

示例:

条件判断(多个条件时)三目运算(只有一个条件时)
a = 3a = 3
if a > 5:b = True if a>5 else False
b = Trueprint(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


@boom3
def eat3(name):
   return '小明和%s在吃东西' % name

print(eat3('小红'))

# 运行结果
小明和小红在吃东西并且爆炸了
(五) 其他装饰器

class Rectangle:
   def __init__(self, length, width):
       self.length = length
       self.width = width

   def area(self):
       areas = self.length * self.width
       return areas

# 像访问属性一样
   @property
   def areal(self):
       return self.width *self.length


#静态方法
   @staticmethod
   def func(): #如果写了self在调用时会报错
       print('staticmethod func')



#类方法
   @classmethod
   def show(cls): #cls代表类本身 如果加上self在调用时要把实例传入
       print(cls)
       print('show fun')
       
       

       
# 用类做装饰器
class TestClass(object):
   def __init__(self, func):
       self.func = func

   def __call__(self, *args, **kwargs):
       print('1234')
       return self.func()

@TestClass
def shuzi():
   print('5678')

shuzi()


# 运行结果
1234
5678
(六) 装饰器参考

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文件(慎用!)
-print假设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  #装饰器要装饰到别的函数上不能直接调用


@run_time   # 装饰器的实质把一个函数换成另一个函数
def func1(a):
   print(type(a))


@run_time
def func2(a, b):
   print(isinstance(a, b))

func1(1)
func2('hello', int)

# 运行结果
<class 'int'>
程序的运行时间是:0:00:00.001849
False
程序的运行时间是:0:00:00.001265

 

一,文件基本操作

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,分为四大类:

类型描述
SystemExitpython退出异常
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)

三,括展

1,re.match(从开头进行匹配和^相似,匹配不到返回none)
2,re.search(只能找到第一个,匹配不到返回none)
3,re.sub(替换,例:r'\d', 'haha', mystr 替换成haha)

转载于:https://www.cnblogs.com/wangshixiong576422/p/9703271.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值