Python基础

Posted by Wh0ami-hy on January 26, 2023

1. python3.x特性

1.1. python编码问题

  • python3.x 默认的内部编码是Unicode,默认的文件编码是utf-8
  • 代码中的字符串的默认编码与代码文件本身的编码是一致的
  • python的内部编码为unicode,与文件本身的编码无关

1.1.1. 声明文件编码

  • # -*- coding: UTF-8 -*-
  • #coding=utf-8

1.1.2. 文件编码

文件本身的编码指的是文件保存在磁盘上时所使用的字符编码,通常使用UTF-8编码或其他编码方式

1.1.3. 内部编码

内部编码指的是Python解释器在内存中使用的字符编码,也是默认的字符串编码方式。Python 3.x 中默认的内部编码是Unicode(UTF-8编码的一种),所以支持多种语言和字符集。当我们读取文件或从其他数据源中获取数据时,Python会自动将其转换为内部编码,当我们将数据写入文件或在屏幕上输出时,Python也会自动将其转换为指定的编码方式。

这一点和 Java 一样

1.2. 其他特性

  • python对大小写敏感
  • python通过缩进来控制结构层次(通常4个空格为一个标准缩进)
  • 使用斜杠\ 实现换行代码的衔接
  • id() 获取内存地址
  • type() 获取数据类型
  • help(方法名称) 查看某方法的使用
  • import + 库名 导入库
  • 库名.方法名 调用库中某方法
  • python库安装和卸载
安装:pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple

卸载: pip uninstall 库名
  • 更新pip
cmd下运行python -m pip install --upgrade pip

2. python编写规范

Python PEP8 编码规范

3. python编译

.pyc文件是py文件编译后生成的字节码文件(byte code)。pyc文件经过python解释器最终会生成机器码运行。所以pyc文件是可以跨平台部署的,类似Java的.class文件。

生成单个pyc文件

python -m foo.py

批量生成pyc文件

python -m compileall <dir>

4. 交互式编程

即直接在终端(如 cmd )中运行解释器,而不使用文件名的方式来执行文件。这种交互式的编程环境,我们也可以称之为REPL,即读取(Read)输入的内容,执行(Eval)用户输入的指令,打印(Print)执行结果,然后进行循环(Loop),Python支持交互式编程

ipython是一个python的交互式shell,比默认的python shell好用得多,支持变量自动补全,自动缩进,支持bash shell命令,内置了许多很有用的功能和函数

5. 注释符

#

6. 变量

只要定义了一个变量,而且它有数据,那么它的类型就已经确定了,不需要开发者主动的去说明它的类型,系统会自动辨别。变量没有类型,数据才有类型

同时为多个变量赋值

x, y, z = "Orange", "Banana", "Cherry"

交换a b的值

a,b=b,a 

+号连接字符

x = "awesome"
print("Python is " + x)

* 重复多次

x= 'abc'
print(x*2)
#结果为 abcabc

7. 数据类型

7.1. 数字类型(Number)

包括整型、浮点型、复数等

7.2. 字符串类型(String)

用于表示文本数据,可以使用单引号、双引号或三引号来定义字符串

7.3. 列表类型(List)

用于存储一组有序的元素,可以包含不同类型的元素,通过索引访问元素。

7.4. 元组类型(Tuple)

类似于列表,但是元组中的元素不可修改,通常用于存储不可变的数据。

7.5. 集合类型(Set)

用于存储一组不重复的元素,可以进行交、并、差等集合运算。

7.6. 字典类型(Dictionary)

用于存储键值对,可以通过键来访问对应的值,键必须是不可变的类型。

7.7. 布尔类型(Boolean)

用于表示真(True)和假(False)两种状态。

不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组)

可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)

7.8. 常用运算

科学计数

科学计数法
1.5 x 10^11表示为

1.5e11
这里e和E不区分大小写

复数

复数由实数部分和虚数部分组成,实数部分和虚数部分都是浮点型,虚数部分必须有后缀j或J

print (64.375+1j)
结果为64.375+1j

7.9. 类型转换

  • set(s) 转换为可变集合
  • int() 转换为整型
  • str() 转换为字符型
  • float() 转换为浮点型
  • bool(x) 布尔型转换

在python3中,只有空字符串''"" 、数字0、空字典{}、空列表[]、空元组()、空数据None会被转换成为False,其他的都会被转换成为True

  • unichr(x) ASCII码转为Unicode单字符串
  • abs() 取绝对值
  • round 四舍五入保留指定小数位
  • sum 求和
  • type() 查看数据的类型

8. 标识符

标识符是用户编程时使用的名字,用于给变量、常量、函数、语句块等命名

8.1. 标识符命名

  • 由字母、下划线和数字组成,且数字不能开头

  • 严格区分大小写

  • 不能使用关键字

8.2. 驼峰命名法

  • 大驼峰命名法:FirstName、LastName

  • 小驼峰命名法:myName、aDog

注意

  • 变量名,函数名和文件名全小写,使用下划线连接
  • 类名遵守大驼峰命名法
  • 常量名全大写

9. 关键字

一些具有特殊功能的标识符

10. 输入输出

10.1. 输入(input)

10.1.1. 语法

返回字符串类型

input('提示信息')

同时输入多个值

a,b,c=input().split(' ')  #输入a,b,c时 将a、b、c用空格隔开 

10.2. 输出(print)

10.2.1. 语法

print(value,sep,end)

10.2.2. 参数

sep

输出时,每个值使用哪种符号分割,默认使用空格

print(123,789,sep='----')
#结果是 123----789

end

执行完一个print语句后,接下来要输出的字符,默认是\n

print(123,789,end='????')
#结果是 123 789????

10.2.3. 格式化输出

格式符号 转换
%% 输出 %
%s 字符串
%d 有符号十进制整数
%f 浮点数
%c 字符
%u 无符号十进制整数
%o 八进制整数
%x 十六进制整数(小写字母0x)
%X 十六进制整数(大写字母0X)
%e 科学计数法(小写e)
%E 科学计数法(大写E)
%g %f%e 的简写
%G %f%E的简写

格式化操作符辅助指令

符号 功能
* 定义宽度或者小数点精度
- 用做左对齐
+ 在正数前面显示加号( + )
<sp> 在正数前面显示空格
# 在八进制数前面显示零0,在十六进制前面显示0x或者0X
0 显示的数字前面填充’0’而不是默认的空格
(var) 映射变量(字典参数)
m.n m 是显示的最小总宽度,n 是小数点后的位数

11. 进制

11.1. 进制的表示

  • 二进制0b开头
  • 八进制0o开头
  • 十六进制0x开头

11.2. 进制转换

  • hex(x)

将一个整数转换为一个十六进制字符串

  • oct(x)

将一个整数转换为一个八进制字符串

  • bin(x)

整型转为二进制字符串

  • int(x,base)

将字符串,转为指定进制(base)

x = '21'
x = int(x,8)	#转为 8 进制
print(x)
#结果为 17

y = 'abc'
y = int(y,16)	#转为 16 进制
print(y)
#结果为 2748

12. 运算符

12.1. 赋值运算符

=

x,*y = 1,3,4,5,6	# * 设置y的长度可变
print(y)
#结果是 [3,4,5,6]

12.2. 算术运算符

  • /
  • *
  • -
  • +
  • 取余%
  • 幂次**
  • //

返回商的整数部分,向下取整,如,5//2,得2

  • ()提高运算优先级

12.3. 关系运算符

  • >
  • ` < `
  • >=
  • ` <= `
  • !=
  • ==

比较内存地址

12.3.1. 字符串使用关系运算符

  • 数字和字符串做== 运算,结果是 false
  • 数字和字符串做除了==以外的逻辑运算时,会直接报错
  • 两个字符串进行比较,会将每个字符都转换成对应的ASCII编码,然后逐一进行对比
x = 'abc'
y = 'b'
if y>=x:
    print('大')

12.4. 逻辑运算符

and

只要有一个运算数是False,结果就是False

只有所有的运算数都为True时,结果才是True

做取值运算时,取第一个为False的值,如果所 有的值都为True,取最后一个值

or

只要有一个运算数是True,结果就是True

只有所有的运算数都为False时,结果才是 False

做取值运算时,取第一个为True的值,如果所 有的值都为False,取最后一个值

not

取反

12.5. 成员运算符

用来判断一个东西(比如变量)是不是在另一个范围(比如列表/字典/元组)里面,若是返回True 否则返回False

  • in
  • not in

12.6. 身份运算符

  • is

判断两个对象是否是同一个对象

12.7. 布尔类型

  • True
  • False

12.8. 位运算符

按位运算符是把数字看作二进制来进行计算的

& 按位与

两个相应位都为1,则该位的结果为1,否则为0

a = 0b110
b = 0b111
print(a&b)
#结果为 6

| 按位或

两个相应位相同为0,不同为1

a = 0b110
b = 0b111
print(a|b)
#结果为 7

^ 按位异或

两个相应位相异时,结果为1,否则为 0

a = 0b110
b = 0b111
print(a^b)
#结果为 1

~ 按位取反

对数据的每个二进制位取反,把1变为0,把0变为1

~x 类似于 -x-1

b = 0b111
print(~b)
#结果为 -8

<< 左移动运算

运算数的各二进位全部左移若干位,由 << 右边的数字指定移动的位数,高位丢弃,低位补0

b = 0b1
print(b<<3)
#结果为 8

>> 右移动运算

运算数的各二进位全部右移若干位,由 >> 左边的数字指定移动的位数

b = 0b100
print(b>>2)
#结果为 1

13. 字符串

13.1. 表示方式

  • 使用'"来创建字符串
  • 三引号允许一个字符串跨多行,字符串中可以包含换行符、制表符以及其他特殊字符

13.2. 转义

python用反斜杠\转义字符

\(在行尾时) 续行符
\\ 反斜杠符号
\' 单引号
\" 双引号
\a 响铃
\b 退格(Backspace)
\e 转义
\000
\n 换行
\v 纵向制表符
\t 横向制表符
\r 回车
\f 换页
\oyy 八进制数,yy代表的字符,例如:\o12代表换行
\xyy 十六进制数,yy代表的字符,例如:\x0a代表换行
\other 其它的字符以普通格式输出

13.3. 索引

s[i]
  • 返回s中的第i个元素,i是序列的序号

  • 正下标正向找,负下标逆向找

13.4. 切片

s[start:end:step]
  • 返回序列s中第start到end-1 以step 为步长的元素子序列

  • step若为负数,表示倒数(倒数是从第0个开始的)

  • start和end若为负数,表示从右边数

  • 倒序 y = s[::-1]

  • 倒数第4个 到 倒数第1个y = s[-4:-1]

  • 从下标为7的元素开始包含下标为7的元素,倒着取到下标为2的元素不包括下标为2的元素s[7:2:-1]

注:切片时必须在最后字符后再加1,因为python只会截取到最后字符的前一个字符

13.5. 常用方法

获取长度

len()

查找

  • find()

    查找指定内容在字符串中是否存在,如果存在就返回该内容在字符串中第一次出现的开始位置索引值,如果不存在,则返回-1

    S.find(sub[, start[, end]])
    
    • index 跟find()方法一样,只不过,未找到时,会报异常

    • rfind 是从右边开始查找的

    • rindex 是从右边开始查找的

判断

  • startswith 判断字符串是否以指定内容开始

  • endswith 判断字符串是否以指定内容结束

  • isalpha 判断字符串是否是纯字母

  • isdigit 判断一个字符串是否是纯数字

  • isalnum 判断是否由数字和字母组成

  • isspace 只包含空格,则返回 True,否则返回 False

出现的次数

count()

替换

replace()

s.replace('被替换的','替换的')

切割字符串

如果 maxsplit 有指定值,则仅分隔 maxsplit + 1 个子字符串

  s.split('分割字符',maxsplit)
  s.split('-',2)
  • split 以指定字符串为分隔符切片,返回的结果是一个列表

  • rsplit 从右往左分隔

  • splitlines 按照行分隔,返回一个包含各行作为元素的列表

  • partition 把字符串分割成三部分,str前,str和str后,三部分组成一个元组

  • rpartition 从右边开始

大小写

  • capitalize 第一个单词的首字母大写

  • title 每个单词的首字母大写

  • lower 所有都变成小写

  • upper 所有都变成大写

空格处理

  • ljust

    返回指定长度的字符串,并在右侧使用空白字符补全(左对齐)

    str = 'hello'
    print(str.ljust(10))
    
  • rjust

    返回指定长度的字符串,并在左侧使用空白字符补全(右对齐)

  • center

    返回指定长度的字符串,并在两端使用空白字符补全(居中对齐)

  • lstrip

    删除字符串左边的空白字符

  • rstrip

    删除字符串右边的空白字符

  • strip

    删除字符串两边的空白字符

字符串拼接

把参数进行遍历,取出参数里的每一项,然后再在后面加上字符串

S.join(iterable)

作用:可以把列表或者元组快速的转变成为字符串,并且以指定的字符分隔

x = '-'
print(x.join(['abc','dcdf']))
#结果是 abc-dcdf

13.6. 字符串运算符

下表实例变量a值为字符串”Hello”,b变量值为”Python”

操作符 描述 实例
+ 字符串连接 a + b 输出结果: HelloPython
* 重复输出字符串 a*2 输出结果:HelloHello
in 如果字符串中包含给定的字符返回 True H in a 输出结果 1
not in 如果字符串中不包含给定的字符返回 True M not in a 输出结果 1
r、R 原生字符串:所有的字符串都是直接按照字面的意思来使用,没有转义特殊或不能打印的字符。原始字符串除在字符串的第一个引号前加上字母”r”(可以大小写)以外,与普通字符串有着几乎完全相同的语法 print r'\n' 输出 \n 和 print R'\n'输出 \n

13.7. 字符集

13.7.1. 字符和编码相互转换

  • chr(x) 将一个ASCII转换为一个字符
  • ord(x) 将一个字符转换为它的ASCII值

13.7.2. 编码规则

按照一定的编码规则对Unicode数字进行计算,得出新的编码。在中国常用的字符编码有 GBK,Big5,utf8三种编码规则

  • encode方法

可以将字符串按照指定的编码格式转换为二进制

  • decode方法

可以将一个二进制数据按照指定的编码格式转换成为字符串

x = b'\xe4\xbd\xa0'

print(x.decode('utf-8'))
  • Unicode 字符串

引号前小写的”u”表示这里创建的是一个 Unicode 字符串

s=u"hello word"
  • 默认字符串是Unicode类型,该类型字符串只能保存在内存中

  • bytes类型字符串,可以保存在磁盘和网络间数据传输

  • 字符串从Unicode到bytes,需要编码:str.enconde("utf-8")

  • 字符串从bytes到Unicode,需要解码:str.decode("utf-8")

13.8. 格式化输出

  • %占位符,格式化一个字符串
a = 16
b = 'zhao'
print('my age is %d my  name is %s'%(a,b))
#结果为 my age is 16 my  name is zhao
  • {}占位符,格式化一个字符串

{}中什么都不写,会读取后面的内容,一一对应填充

print('my name is {} my age is {}'.format('123','456'))
#结果为 my name is 123 my age is 456

{数字}数字就是值的下标(从0开始)

print('my name is {1} my age is {0}'.format('123','456'))
#结果为 my name is 456 my age is 123

{变量名}

print('my name is {name} my age is {age}'.format(name = '123',age = '456'))
#结果为 my name is 123 my age is 456

{数字}{变量}混合使用

{}和列表使用

使用*列表名传参,{}中什么都不填

a = [1,5,'bv']
print('my name is {} my age is {}'.format(*a))
#结果为 my name is 1 my age is 5

{}和字典使用

使用**字典名传参,{}中填写字典中的键名

b = {'name':'zhao','age':16,'high':180}
print(*b)
#结果为 name age high
print('my name is {name} my age is {age}'.format(**b))
#结果为 my name is zhao my age is 16

13.9. 拆包

*加一个序列(列表、元组等)表示拆包,即将一个数据拆成多个数据

a = (1,2,3,5)
print('my name is {} my age is {}'.format(*a))
#结果是 my name is 1 my age is 2
print(a)
#结果是 (1, 2, 3, 5)
print(*a)
#结果是 1 2 3 5

14. 列表(list)

  • 格式 []
  • 列表的数据项不需要具有相同的类型,无论那是字符、字符串或者是另个列表
  • 是有序的
  • 索引从0开始计数

14.1. 切片

  • 格式:[start:end:step],第一个参数,是开始切割的位置,第二个参数,是结束切割的位置,第三个参数,是步长
  • 倒序:[::-1]

14.2. 列表运算符

+

将两个列表合并

14.3. 列表推导式

指的是轻量级循环创建列表

数字型
a=[i for i in range(20) if i%2==0]
#语法,我们使用了一个临时声明的变量x,x后面跟了一个for循环,使用range迭代返回的每一个值。这些东西都被放进了列表里
字符型
b=['NAme','Is']
b=[x.lower() for x in b]

14.4. 列表的复制

  • 直接使用=,得到的两个列表指向同一个地址

  • copy()方法

得到的两个列表指向不同的地址

  • copy模块
    • 浅拷贝
    • 深拷贝

14.5. 列表的遍历

enumerate()

带下标的遍历

test = [84,55,12,2]
en = enumerate(test)

for i in en:
    print(i)
   
#结果是
(0, 84)
(1, 55)
(2, 12)
(3, 2)

for i,e in en:
    print('第%d个元素是%d'%(i,e))
    
#结果是
第0个元素是84
第1个元素是55
第2个元素是12
第3个元素是2

14.6. 修改列表元素

通过遍历整个列表,修改值

num  =range(5)
for  item in num:
	item = item*2

# 以上代码无法修改列表中的元素,因为原因item 的id(地址)  已经不是原来的id(地址)

正确方法,使用带下标的遍历

num = range(5)
for i, item  in  enumerate(num):
	num[i] =num[i]*2

14.7. 常用方法

将元组转换为列表

list(seq)

添加元素

  • append()

接收一个参数。把接收到的参数放在列表的末尾

  a=['a','d','w']
  a.append('q')
  a.append(1)
  #结果为['a', 'd', 'w', 'q', 1]
  • insert(index,object)

接收两个参数,index参数表示在列表的哪个索引位置上进行插入,object表示要插入的值

  a=['a','d','w']
  a.insert(2,'1')
  #结果为['a', 'd', '1', 'w']
  • extend(seq)

在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)

  a = [1,2,3]
  b = [4,5,6]
  
  a.extend(b)
  print(a)
  #结果为 [1, 2, 3, 4, 5, 6]

删除元素

  • remove()

删除特定的值(列表中第一次出现的),并不能根据我们给定的索引进行删除

  a=['a','d','w','a','g','a']
  a.remove('a')
  #结果为['d', 'w', 'a', 'g', 'a']
  • del()

删除指定索引位的值

  a=['a','d','w']
  del(a[2])
  #结果为['a', 'd']
  • pop()

移除列表中指定索引位的值,并且返回该元素的值,默认删除最后一个元素

  • clear()

清空一个列表

查询元素

运算符 in

列表元素个数

len()

找最大最小值

  • max()
  • min()

统计某个元素在列表中出现的次数

count()

从列表中找出某个值第一个匹配项的索引位置

index()

元素反转

reverse()

排序

  • sorted()

排序内置函数,不会改变原有数据,而是排序后返回一个有序的列表

  • sort(cmp=None, key=None, reverse=False)

对原列表进行排序,reverse=False正序排,reverse=True逆序排

key的参数类型是函数,需要传递参数key来确定排序规则

#对列表中的字典元素进行排序,因为字典有多个参数,那么根据哪一个参数进行排序呢??
student = [
    {'name':'zhangsan','age':14,'score':98},
    {'name':'lier','age':17,'score':68},
    {'name':'zhaoshi','age':19,'score':78}
     ]

def foo(a):		#可以打印,看一下a的值
    return a['age']	#通过返回值告诉sort排序规则,这里是按照age排序
    

student.sort()	#直接进行排序会报错:TypeError: '<' not supported between instances of 'dict' and 'dict' 
print(student)					#说明字典间无法直接比较,无法排序
    
student.sort(key=foo)	#给key传一个函数,在sort函数内部会调用foo函数
print(student)

#foo函数还可以直接写在sort的参数中,student.sort(key=lambda x:x['age'])

15. 元组 (tuple)

  • 格式()
  • 只能读不能写的列表
  • 定义只有一个元素的元组时,要在一个元素后加逗号

    a=('3',)  #类型为元组
    a=('3')   #类型为字符
    

15.1. 常用方法

  • tuple(seq)

将列表转换为元组

  • index()
  • count()

注意

元组的增删查改是基于整个元组改变的,而若想改变里面的元素,应该用列表(list)

16. 字典( dict)

  • 格式 { : } 键值对
  • 字典的值可以是任意类型的数据

16.1. 字典推导式

16.2. 常用操作

  • 查看元素

    • 提取出字典中的值

    字典名['键名']

    a = {'name':'zhaoshi','age':16}
    print(a['name'])
    #结果为 zhaoshi
    
    • .get()

    提取出字典中的值

    a = {'name':'value'}
    print(a.get('name'))
    #结果为 value
    
  • 添加元素

字典名['键名'] = 添加的值,如果这个值在字典中,不存在,那么就会新增这个元素

a = {'name':'value'}
a['age'] = 12
print(a)
#结果为 {'name': 'value', 'age': 12}
  • 删除元素

    • pop()

    删除键名对应的键值

    a = {'name':'value','age':16}
    b = a.pop('name')
    print(a)
    #结果为 {'age': 16}
    
    • popitem()

    • del

    del 字典名['键名']

    a = {'name':'value','age':16}
    del(a['name'])
    print(a)
    #结果为 {'age': 16}
    

    del 字典名

    删除整个字典

    • clear()

    清空整个字典

    a = {'name':'value','age':16}
    a.clear()
    print(a)
    #结果为 {}
    

16.3. 常用方法

  • str()

将字典以字符串表示

  • .keys()

显示字典里的所有键名

a = {'name':'value','age':16}
b = a.keys()
for i in b:
    print(i)
#结果为 
# name
# age
  • .values()

显示所有的值

a = {'name':'value','age':16}
b = a.values()
for i in b:
    print(i)
#结果为 
# value
# 16
  • .items()

显示所有的关键字和他们的值(同时显示)

a = {'name':'value','age':16}
b = a.items()
for i,j in b:
    print(i,j)
#结果为
# name value
# age 16
  • update()

在字典末尾一次性追加另一个字典(用新字典扩展原来的字典)

a = {'name':'value','age':16}
c = {'test':123}
a.update(c)
print(a)
#结果为 {'name': 'value', 'age': 16, 'test': 123}

17. 集合 (set )

  • 格式{}
  • 不能有重复元素
  • 只读不写
  • 无序
  • 空集合 set()

17.1. 操作

17.1.1. 更新集合

  • .add(elem)

将元素 elem添加到集合中

  • .pop()

随机删除一个元素

  • .update()

A.update(B)`B拼接到A里

  • .remove(elem)

删除elem元素

如果元素不存在,则会发生错误

  • discard(elem)

如果元素不存在,不会发生错误

  • .clear()

清空集合

17.1.2. 联合|

与集合的OR操作其实等价的,联合符号有个等价的方法,union()

s1=set('abcdde')

s2=set([1,2,3,4,5])

s4=s1|s2

print s4
结果为{'e', 1, 2, 3, 4, 5, 'a', 'd', 'b', 'c'}

17.1.3. 交集&

与集合AND等价,交集符号的等价方法是intersection()

17.1.4. 差集-

等价方法是difference()

17.1.5. 异或^

求两集合差集的并集

18. 序列的转换

18.1. set()

18.2. list()

18.3. tuple()

18.4. eval()

称为评估函数,作用是去掉参数中最外层引号并执行剩余语句

可转换序列的类型

    a = '465'
    print(type(a))		# 字符串类型
    print(type(eval(a)))	# int类型

多被用来执行字符串里的代码

a = 'input("请输入")'	#字符串
eval(a)	#执行字符串里的代码

18.5. 转JSON

  • 引入json模块
import json
  • .dumps()方法

.dumps()将字典、列表、集合等转换为JSON字符串

import json
person = {'name':'zhangsan','age':18}
m = json.dumps(person)
print(m)
#结果
# '{"name": "zhangsan", "age": 18}'

  • .loads()方法

将JSON字符串转换为python对应的类型,字典、列表等

19. 流程控制

19.1. 条件判断

If

else

elif

a=int(input())
if a==1:
    print('a=1')
elif a==2:
    print('a=2')
else:
    print('error')

19.2. 循环结构

19.2.1. 相关函数

  • range()

range函数可以有三个参数,第一个参数作为下界,第二个参数作为上界,第三个参数为步长,返回一个含有数值类型的列表

a=range(1,10)
b=list(a)
print(b)
#结果为[1, 2, 3, 4, 5, 6, 7, 8, 9]
  • len()

返回变量的长度,无论这个变量是string类型,list类型亦或是dictionary类型

19.2.2. for

一般用于循环次数可知

19.2.3. while

一般用于循环次数未知

19.2.4. 结束循环

  • BREAK ,用于跳出最近的一级for或while循环
  • CONTINUE,表示结束本次循环,继续执行下一次迭代
  • PASS,用于那些语法上必须要有什么语句,但程序什么也不做的场合。通常我们使用pass语句来进行占位

20. 函数

20.1. 全局变量

在函数外声明的变量,可以在脚本程序的任意位置调用这个变量

20.1.1. global

用来在函数内部修改全局变量

x = 50
def func():
    x = 2
    print(x)

func()
print(x)
#改变的是局部变量x,外部x不受影响

def func():
    global x
    x = 2
    print(x)
    
func()
print(x)
#注意:当x被定义为全局变量时,x就不能被当作形参传入函数中

20.1.2. 相关函数

内置函数

  • globals() 查看全局变量
  • locals() 查看局部变量

20.2. 局部变量

在函数里声明的变量,只能在函数内部被调用而不能在函数外部调用

注:如果在函数范围内定义了具有相同名称的变量,那么它将仅打印函数内给出的值而不是全局值

20.3. 函数名

函数名相当于变量,指向函数体中的代码

def a():
    print("输出a");
b = a;	#相当于给函数起个别名

b();	#结果是 输出a

20.4. 函数的回调

把该函数当作参数传给另一个函数

#运算 a b
def calc(a,b,fun):
    c = fun(a,b)
    return c

def add(a,b):
    return a + b

def jian(a,b):
    return a - b

#把函数名当作参数传递给另一个函数,就可以在另一个函数中调用
calc(5,2,add)	#调用加法函数
calc(5,2,jian)	#调用减法函数
    
    

20.5. def声明函数

20.5.1. 调用函数

  • 函数名(参数)
def greet():
    pass
    
greet();

20.6. 传参

20.6.1. 缺省参数

形参中默认有值的参数

有默认值的参数,一定要位于参数列表的最后面

def func(a, b=5)

#是有效的,但是

def func(a=5, b)

#是无效的

20.6.2. 关键字传参

此方法,不必担心参数的顺序

def func(x=2,y=3):
    z=x+y
    print(z)

func(y=1,x=3)
#尽管函数定义中,x在y之前定义,我们仍然可以在x之前指定参数y的值。

20.6.3. 传多个参数

将多个数据捆绑到一个列表、字典、元组中等,传入函数中

#求多个数的和
def add(num):
    x = 0
    for i in num:
        x+=i
    return x
        
num = [1,2,3,4,5]
print(add(num))

20.6.4. 可变参数

可变参数允许传入在函数声明时,没有命名的参数

  • *args

表示可变位置参数(一般的参数),多出来的参数会以元组的形式保存到args里

def add(a,b,*args):
    
    print('arg = {}'.format(args))
    
add(1,2,4,5,6,7)
#结果是 arg = (4, 5, 6, 7)
  • **kwargs

表示可变关键字参数,多出来的参数会以字典的形式保存到kwargs里

def add(a,b,**kwargs):

    print('kwargs = {}'.format(kwargs))

add(1,2,x = 4,y = 5)
#结果是  kwargs = {'x': 4, 'y': 5}

20.6.5. 参数的顺序

一般参数,*args,缺省参数,**kwargs

20.7. return

如果一个函数没有返回值,它的返回值就是None

20.7.1. 返回多个值

将多个数据捆绑到一个列表、字典、元组中等

def test(a,b):
	x = a//b
    y = a%b
    return [x,y]
	return x,y	#默认返回的是元组
    
result = test(10,3)
print(result[0],result[1])

20.8. 函数的文档说明

三个双引号

def add():
"""
说明内容
"""

20.9. lambda匿名函数

  • 格式: lambda 参数 :参数的运算式
  • lambda表达式必须被赋值给某个变量才能发挥作用
  • 作用:用来表达一个简单的函数,调用次数很少

20.9.1. 调用函数

  • 给函数命名(使用较少)
f=lambda x,y : x+y

print(f(1, 2))  #计算两数之和,输出:3
  • 函数回调
def calc(a,b,fun):
    c = fun(a,b)
    return c

x1 = calc(5,2,lambda x,y:x+y)	#计算加法

x2 = calc(5,2,lambda x,y:x-y)	#计算减法

x3 = calc(5,2,lambda x,y:x/y)	#计算除法

print(x1)

20.9.2. lambda操作符

  • fliter()

对可迭代对象进行过滤

可以被用来过滤原有的list,并把过滤结果放进新的list里。filter接受两个参数,第一个是lambda表达式提供的过滤条件,第二个是要进行过滤的现有列表。最后,filter返回一个符合条件的列表类型

from functools import fliter
a=[x for x in range(1,10)]
b=filter(lambda i:i%2==0,a)#将列表中符合条件的值,过滤出来
print(b)
#结果为[2, 4, 6, 8]
  • map()

可以同时对list里的所有元素进行操作,并以列表方式给出返回值

from functools import map
a=[x for x in range(1,10)]
b=map(lambda i:i**2,a)#将列表里的内容都平方
print(b)
#结果为[1, 4, 9, 16, 25, 36, 49, 64, 81]
  • reduce()

可以对列表顺序执行算术运算

from functools import reduce
a = [1, 4, 9, 16, 25, 36, 49, 64, 81]
b = reduce(lambda x,y:x+y,a)#将列表里的内容相加,具体过程:x = 1,y = 4;x = 1 + 4,y = 9;x = 1+ 4 + 9..
print(b)
#结果为[1, 4, 9, 16, 25, 36, 49, 64, 81]

高级操作

#对列表中字典元素的年龄进行求和,因为字典有多个参数,那么如何让年龄求和呢??
from functools import reduce

student = [
    {'name':'zhangsan','age':14,'score':98},
    {'name':'lier','age':17,'score':68},
    {'name':'zhaoshi','age':19,'score':78}
     ]
def bar(x,y):
    
b = reduce(bar,student,0)#定义一个bar函数实现,列表内字典元素的相加,并给x一个初始值 0
print(b)	#结果为 50

20.10. 常用内置函数

  • dir()

列出对象的所有方法

  • isinstance

判断一个对象是否由一个类创建出来

  • issubclass

判断一个类是否为另一个类的子类

  • iter

获取可迭代对象的迭代器

  • sorted

排序

20.11. 高阶函数

  • 将函数作为另一个函数的返回值
def old():
    print('我被old调用了')
    return old

def new():
    print('我被new掉调用了')

    # return old()
    return old	#将函数名作为返回值

a = new()
a()	#调用返回的函数

  • 函数中定义函数
def outer():
    m = 10
    def inner():
        n = 90
        print('我是inner')
     print('我是outer')
    
    return inner	#返回函数名

outer()	#调用outer函数
outer()()	#先调用outer后调用inner
  • 闭包

在内部函数里对外部函数的变量进行调用

在内部函数里对外部函数的变量进行修改,需要用nonlocal声明

def outer():
    m = 10
    print(m)
    
    def inner():
        nonlocal m	#nonlocal,进行声明
        m = 50		#修改外部函数变量的值
        print(m)
    if True:
        inner()
    print(m)	#前面如果不用nonlocal声明,这里将打印 10而不是50

21. 装饰器

@声明一个装饰器

给某个函数加装饰器,在该函数的前一行,声明装饰器即可

import time

def cal_time(fun):
    print('外部函数被调用')

    def inner():
        start = time.time()
        fun()
        end = time.time()
        print('本次程序耗时',end-start)

    return inner

@cal_time   #相当于cal_time(demo)
		   #装饰器
            #第一件事,调用cal_time
            #第二件事,把装饰器的函数传递给fun
            #第三件事,再次调用demo时,执行的已经不是以前的demo

def demo():
    x = 0
    for i in range(1,100000):
        x+=i
    print('demo被执行')

demo()	#执行的已经不是以前的demo,而是cal_time函数内的inner函数,通过inner函数来调用demo函数

21.1. 被修饰的函数无参数

def check_time(action):
    print('check_time被调用')
    def do_action():
        action()
        print('do_action被调用')

    return do_action

@check_time	#会调用check_time

def go_to_bad():
    print('上床睡觉')

go_to_bad()	#实际上调用的是do_action

21.2. 被修饰的函数有参数

def check_time(action):
    print('check_time被调用')
    def do_action(name):
        action(name)
        print('do_action被调用')

    return do_action

@check_time

def go_to_bad(name):
    print('{}上床睡觉'.format(name))

go_to_bad('张三')

21.3. 被修饰的函数有不定长参数

def check_time(action):
    print('check_time被调用')
    def do_action(*args):
        action(*args)
        print('do_action被调用')

    return do_action

@check_time

def go_to_bad(*args):
    sum = 0
    for x in args:
        sum +=x
    print(sum)

go_to_bad(1,2,3,4,5)

21.4. 装饰器中的return

22. 模块(module)

  • python里,一个.py文件就是一个模块
  • .py文件的命名必须遵守规则:由字母、数字、下划线构成,不能以数字开头

22.1. 导入模块

  • import 模块名

直接导入一个模块

  • from 模块名 import 函数名

导入一个模块里的方法或变量

  • from 模块名 import *

导入这个模块的所有方法和变量(不是所有),使用该方法导入一个模块里所有的内容时,本质上是去查找这个模块的 __all__属性,将 __all__ 属性里声明的所有内容导入。如果这个模块里没有设置 __all__ 属性,此时才会导入这个模块里的所有内容

  • import 模块名 as 别名

导入一个模块并为其起别名

  • from 模块名 import 函数名 as 别名

22.2. pip

  • pip install 模块名

下载第三方模块

  • pip uninstall 模块名

卸载第三方模块

  • pip freeze

列出当前环境安装模块名和版本号

  • pip freeze > filename

将安装的模块名和版本号重定向输出到指定的文件

  • pip install -r filename

读取文件中的模块名和版本号并安装。该方法常用于将代码部署到服务器时,给服务器的python安装模块

  • pip install 模块名 -i 源的地址

(临时的)更改模块的下载源

  • 永久更改源地址

在当前用户目录下(C:\Users\用户名)创建一个pip的文件夹,然后再在文件夹里创建pip.ini文件并输入以下内容

[global]
index-url=https://pypi.douban.com/simple
[install]
trusted-host=pypi.douban.com
#国内镜像
#阿里云 https://mirrors.aliyun.com/pypi/simple/
#中国科技⼤大学 https://pypi.mirrors.ustc.edu.cn/simple/
#豆瓣(douban) https://pypi.douban.com/simple/
#清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/
#中国科学技术大学 https://pypi.mirrors.ustc.edu.cn/simple/

22.3. 模块里的私有成员

模块里以一个下划线 _ 开始的变量和函数,是模块里的私有成员,当模块被导入时,以 _ 开头的变量默认不会被导入。但是它不具有强制性,如果一个代码强行使用以 _ 开头的变量,有时也可以。但是强烈不建议这样使用,因为有可能会出问题

22.4. __all__

一个存放模块变量和方法的列表

22.5. __name__

Python中,当直接运行一个py文件时,这个py文件里的 __name__ 值是 __main__ ,当这个py文件被当作模块导入时 __name__ 的值是文件名 ,据此可以判断一个py文件是被直接执行还是以模块的形式被导入。

if __name__ == '__main__':
    print 'This program is being run by itself'
else:
    print 'I am being imported from another module'

23. 包

一般把 Python 里的一个代码文件夹称为一个包,并在包里创建 __init__.py 文件

导包

以项目根目录为准,输入目标模块 或 包的路径: from spiders._tools import xxx

24. python面向对象编程

可以使用dir内置函数来查看一个对象里的方法

24.1. 定义类

方法里的第一个参数必须是self

class 类名:
    def 方法1(self,参数列表):
        pass
    def 方法2(self,参数列表):
        pass

24.2. 创建实例对象

对象变量名 = 类名()
#如
a = A()
class People:
    def __init__(self,x,y,z):
        self.name = x
        self.age = y
        self.height = z
    def run(self):
        print("正在跑步")

    def eat(self):
        print("正在吃东西")

    def __str__(self):
        return '自动调用print'	

s1 = People('小明',16,180)    #这段代码做了
                            #调用__new__方法用来申请内存空间
                            #调用__init__方法,并让self指向申请好的那段内存空间,填充数据
                            #让s1也指向那段内存空间

print(s1)
#结果:自动调用print

24.3. self的使用

  • 给对象添加属性
class People:
    def __init__(self,x,y,z):
        self.name = x #添加属性
        self.age = y
        self.height = z
  • python支持动态属性,当一个对象创建好了以后,直接使用对象.属性名 = 属性值 就可以很方便的给对象添加一个属性。但是,不建议使用这种方式给对象添加属性
tom = Cat()
tom.name = 'Tom'  # 可以直接给 tom 对象添加⼀一个 name 属性

24.3.1. self概念

哪个对象调用了方法,方法里的self指的就是谁。通过self.属性名可以访问到这个对象的属性。通过self.方法名() 可以调用这个对象的方法

24.4. 魔术方法

  • 特点

两个下划线开始,两个下划线结束的方法

魔术方法在恰当的时候就会被激活,自动执行

  • __init__方法

该方法在创建对象时,会默认被调用

方法里的self参数,在创建对象时不需要传递参数,python解释器会把创建好的对象引 用直接赋值给self

在类的内部,可以使用self来使用属性和调用方法。在类的外部,需要使用对象名来使用属性和调用方法

如果有多个对象,每个对象的属性是各自保存的,都有各自独立的地址

方法是所有对象共享的,只占用一份内存空间,方法被调用时会通过self来判断是哪个对象调用了实例方法

  • __del__方法

该方法在删除对象时,会默认被调用

  • __str__方法

返回对象的描述信息,使用print()函数打印对象时,其实调用的就是这个对象的 __str__ 方法

如果想要修改对象的输出的结果,可以重写 __str__ 方法

  • __repr__方法

__repr__方法和 __str__ 方法功能类似,都是用来修改一个对象的默认打印内容。

在打印一个对象时,如果没有重写 __str__ 方法,它会自动来查找 __repr__ 方法。

如果这两个方法都没有,会直接打印这个对象的内存地址。

如果这两个方法都有,会调用__str__ 方法

  • __call__

对象后面加括号,触发执⾏

class People:
    def __init__(self,x,y,z):
        self.name = x
        self.age = y
        self.height = z
    def run(self):
        print("正在跑步")

    def eat(self):
        print("正在吃东西")

    def __call__(self):
        print("__call方法被调用")

s1 = People('小明',16,180)
                        
s1()	#调用__call__方法


class People:
    def __init__(self,x,y,z):
        self.name = x
        self.age = y
        self.height = z
    def run(self):
        print("正在跑步")

    def eat(self):
        print("正在吃东西")


    def __call__(self,*args,**kwargs):
        print("__call方法被调用")
        print("{}\n".format(args))
        print("{}\n".format(kwargs))
        fun = kwargs['fn']
        print(fun(args[0], args[1]))


s1 = People('小明',16,180)

s1(1,2,fn = lambda x,y:x+y)
  • __eq__

==默认调用对象的__eq__方法,获取该方法的返回值。若__eq__方法不重写,则默认比较内存地址

身份运算符is用来判断两个对象是否是同一个对象

24.5. 对象的内置属性

  • __slots__属性

防止通过动态属性,直接给对象添加属性

class Person(object):
    __slots__ = ('name', 'age')	#限制了动态属性
    def __init__(self, name, age):
        self.name = name
        self.age = age
p = Person('张三', 18)
p.name = '李李四'
p.height = 180	#报错
# 对象p只能设置name和age属性,不能再动态添加属性 p.height = 180
  • __doc__

表示类的描述信息,获取类中的文档说明'''中的内容''',可以类名.__doc__也可以__对象名.__doc__调用

class Person:
    '''一些介绍'''
    def __init__(self, name, age):
        self.name = name
        self.age = age


p = Person('张三', 18)

print(p.__doc__)	#结果:一些介绍
  • __module__

表示当前操作的对象在那个模块

class Person:
    '''一些介绍'''
    def __init__(self, name, age):
        self.name = name
        self.age = age


p = Person('张三', 18)

print(p.__module__)	#结果是 __main__
  • __class__

表示当前操作的对象的类是什么

class Person:
    '''一些介绍'''
    def __init__(self, name, age):
        self.name = name
        self.age = age


p = Person('张三', 18)

print(p.__class__)	#结果是 <class '__main__.Person'>
  • __dict__

以字典的形式,显示对象所有的属性和方法

class Person:
    '''一些介绍'''
    def __init__(self, name, age):
        self.name = name
        self.age = age


p = Person('张三', 18)

print(p.__dict__)	#结果是 {'name': '张三', 'age': 18}

24.6. 类属性和对象属性

  • 类属性可以通过类对象或者实例对象访问
class Person:
    number = '06'	#类属性
    def __init__(self, name, age):
        self.name = name
        self.age = age

p = Person('张三', 18)

print(p.number)	#通过实例对象访问类属性
print(Person.number)	#通过类对象访问类属性
  • 如果有同名实例属性和类属性,实例对象会优先访问实例属性
class Person:
    number = '06'	#类属性
    def __init__(self, name, age,number):
        self.name = name
        self.age = age
        self.number = number	#同名属性

p = Person('张三', 18,'08')

print(p.number)	#结果为08,实例对象会优先访问实例属性
print(Person.number)	##结果为06
  • 类属性只能通过类对象修改,不能通过实例对象修改
class Person:
    number = '06'
    def __init__(self, name, age):
        self.name = name
        self.age = age

p = Person('张三', 18)

p.number = '01'
print(Person.number)	#结果为06
Person.number = '01'
print(Person.number)	#结果为01
  • 类属性也可以设置为私有,前边添加两个下划线

24.7. 私有属性和方法

对象的属性或者方法只可以在对象的内部使用,在外部不能被访问

24.7.1. 定义

在定义属性或方法时,在属性名或者方法名前增加两个下划线 __ ,定义的就是私有属性或方法

24.7.2. 访问私有

  • 直接访问

在私有属性名或方法名前添加_类名

class Person:
    def __init__(self, name, age):
        self.__money = 800	#私有属性
        self.name = name
        self.age = age


p = Person('张三', 18)
print(p._Person__money)	#直接访问私有属性
  • 定义方法访问

可以通过定义getset 方法来实现访问私有

class Person:
    def __init__(self, name, age):
        self.__money = 800
        self.name = name
        self.age = age

    def get(self):
        return self.__money
    def set(self,money):
        self.__money = money
p = Person('张三', 18)
print(p.get())	#结果是 800
p.set(2)	
print(p.get())	#结果是 2

24.8. 类方法

  • 对象方法可以使用实例对象名.方法(参数)调用,该方法不需要为self传参,会自动为self传参
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def demo(self,number):	#类方法
        print(self.name + '学号是' + number)


p = Person('张三', 18)
p.demo('01')	#通过对象调用

#结果 张三学号是01
  • 对象方法还可以使用类名.方法(参数)调用,该方法不会自动为self传参,需要手动指定self
class Person:

    def __init__(self, name, age):
        self.name = name
        self.age = age
    def demo(self,number):
        print(self.name + '学号是' + number)


p = Person('张三', 18)
Person.demo(p,'02')	#通过类调用
#结果 张三学号是02

24.9. 继承

  • 在Python中,继承可以分为单继承、多继承和多层继承
  • 定义类时,在类名的括号后面传入父类的类名,表示子类继承父类
class Animal:
    def __init__(self):
        pass
        '''动物类'''

    def sleep(self):
        print('正在睡觉')

class Dog(Animal):    #继承于Animal类
    '''Dog类继承于Animal类'''
    def __init__(self):
        pass

dog = Dog()
dog.sleep()

24.10. 多态

25. 文件操作

25.1. 手动文件I/O操作

25.1.1. 写文件

file = open('路径','w')
file.write('内容')
file.close()

25.1.2. 读文件

file = open('路径','r')
file.read()
file.close()

注意:定要记得把文件关上。如果不关闭文件,就会导致一些错误,文件也可能会被损坏。

25.2. 自动文件I/O操作

用with关键字和as关键字来打开和关闭文件。会自动关闭文件,不需要close()函数

25.2.1. 写文件

with open('路径','w') as 变量名:
    变量名.write('内容')

25.2.2. 读文件

with open('路径','r') as 变量名:
    变量名.read()

25.3. 相关函数

open()

open(file,mode,encoding)

  • file 文件路径(相对或者绝对路径)

windows中使用\分隔路径,但python中\表示转义符

python中可以使用\\/分割路径,也可以使用r'路径'表示(即在路径前加r)

  • encoding 打开文件时的编码方式

windows中默认使用gbk编码读写文件

  • mode 文件打开模式

    r

    只读(默认模式),如果文件不存在会报错

    w

    打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件

    a

    追加,新内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入

    r+

    打开一个文件用于读或写

    w+

    打开一个文件用于读或写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件

    a+

    打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写

    rb

    以二进制方式读文件

    wb

    以二进制方式写文件,如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件

    ab

    追加,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入

    rb+

    以二进制格式打开一个文件用于读写

    wb+

    以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件

    ab+

    以二进制格式打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写

read()

read(num),num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据,返回的数据类型是一个字符串

readline()

每次读出一行内容,包括 \n字符

#方法1
file = open("foo.txt")

while True:
    content = file.readline()
    print(content)
    if content =='':
        break
file.close()
#方法2
for line in open('文件名')
	print(line)

readlines()

读取整个文件所有行,保存在一个列表中,每行作为一个元素

strip()

使用strip去掉每行结束的\n

for line in file.readlines():

line=line.strip('\n')

write()

写数据,只能写入字符串和二进制

writelines()

写行数据,只能写入字符串和二进制

将多个值同时写入一行中

25.4. 文件指针

  • tell()
  • seek()

25.5. CSV文件的读写

Comma-Separated Values,中文叫逗号分隔值或者字符分割值,其文件以纯文本的形式存储表格数据。可以把它理解为一个表格,只不过这个表格是以纯文本的形式显示的,单元格与单元格之间,默认使用逗号进行分隔,每行数据之间,使用换行进行分隔

25.5.1. CSV文件的写⼊

使用csv模块

import csv
# 以写⼊入⽅式打开⼀个csv⽂件
file = open('test.csv','w')
# 调⽤用writer⽅法,传⼊csv⽂件对象,得到的结果是⼀个CSVWriter对象
writer = csv.writer(file)
# 调⽤CSVWriter对象的writerow⽅法,⼀行一行的写⼊数据
writer.writerow(['name', 'age', 'score'])
# 还可以调⽤writerows⽅法,⼀次性写⼊多行数据
writer.writerows([['zhangsan', '18', '98'],['lisi', '20', '99'], ['wangwu', '17', '90'], ['jerry', '19', '95']])
file.close()

25.5.2. CSV文件的读取

import csv
# 以读取⽅式打开⼀个csv⽂件
file = open('test.csv', 'r')
# 调⽤csv模块的reader⽅法,得到的结果是⼀个可迭代对象reader = csv.reader(file)
# 对结果进行遍历,获取到结果里的每⼀⾏数据
for row in reader:
    print(row)
file.close()

25.6. 内存中写入数据

StringIO和BytesIO

25.7. 序列化和反序列化

通过文件操作,我们可以将字符串写入到一个本地文件。但是,如果是一个对象(如列表、字典、元组等),就无法直接写入到一个文件里,需要对这个对象进行序列化,然后才能写入到文件里

25.7.1. JSON模块

JSON的本质是字符串

反序列化

  • json.loads()

将已编码的 JSON 字符串解码为 Python 对象

  • json.load()

读取文件,把读取的JSON内容解码为 Python 对象

序列化

  • json.dumps()

将 Python 对象编码成 JSON 字符串,不会将数据保存到文件里

  • json.dump()

json.dump(数据,file)

将 Python 对象编码成 JSON 字符串,同时将数据保存到指定文件里

import json
a = {'name':'zhaoshi','age':16}

file = open('test.txt','wb')
file.write(pickle.dumps(a))
file.close()

25.7.2. pickle模块

将对象转换成为二进制(只有python能识别的二进制)

反序列化

  • pickle.loads()

将二进制解码为 Python 对象

  • pickle.load()

读取文件,把读取的二进制内容解码为 Python 对象

序列化

  • pickle.dumps()

将 Python 对象编码成二进制,不会将数据保存到文件里

  • pickle.dump()

json.dump(数据,file)

将 Python 对象编码成二进制,同时将数据保存到指定文件里

import pickle
a = {'name':'zhaoshi','age':16}

file = open('test.txt','wb')
file.write(pickle.dumps(a))
file.close()

file = open('test.txt','rb')
x = file.read()
print(pickle.loads(x))

25.7.3. 对比

  • pickle

pickle序列化是将对象按照一定的规则转换成为二进制保存,它不能跨平台传递数据

pickle的序列化会将对象的所有数据都保存

  • json

将对象转换成为字符串,json就是用来在不同平台间传递数据的

不是所有的对象都可以直接转换成为一个字符串

python JSON
dict object
list、tuple array
str string
int、float number
True true
False false
None null

26. 异常处理

增加程序的稳定性(健壮性),我们应该尽可能的考虑可能发生错误的点以及用户的使用方式,以使得程序不会轻易的崩溃

26.1. try+except

except可以专门处理单一的错误或异常,也可以处理一组在元组中的错误/异常。如果没有给出错误或异常的名称,它会处理所有的错误和异常

try:
可能会出现异常的代码块
except 异常的类型:
出现异常以后的处理理语句

26.2. try+except+else

如果没有捕获到异常,那么就执行else中的代码

try:
    num = 100
    print(num)
except NameError as e:
    print('产⽣生错误了了:%s'%e)
else:
    print('没有捕获到异常,真⾼高兴')

26.3. try+finally

在程序中,如果一段代码必须要执行,即无论异常是否产生都要执行,那么此时就需要使用finally,比如 文件关闭,释放锁,把数据库连接返还给连接池

如果函数里有finally,finally里的返回值会覆盖之前的返回值

def div(a,b):
    try:
        x = a/b
    except:
        return 'error'
    else:
        return x
    finally:
        return '没有捕获到异常,真⾼兴'

print(div(1, 2))
#结果为 没有捕获到异常,真⾼兴

26.4. 自定义异常

用raise语句来引发一个异常。异常/错误对象必须有一个名字,且它们应是Error或Exception类的子类

常用

except Exception as e:

高级

class ShortInputException(Exception):
    '''⾃定义的异常类'''
    def __init__(self, length, atleast):
    #super().__init__()
        self.length = length
        self.atleast = atleast
    def __str__(self):
        return '输入的长度是 %d,长度至少应是 %d'% (self.length, self.atleast)

def main():
    try:
        s = input('请输入 --> ')
        if len(s) < 3:
    # raise 引发一个自定义的异常
            raise ShortInputException(len(s), 3)
    except ShortInputException as result: # x这个变量被绑定到了错误的实例
        print('ShortInputException:' % result)
    else:
        print('没有异常发生.')
main()

26.5. 异常获取

  • str(e)

返回字符串类型,只给出异常信息,不包括异常信息的类型,如1/0的异常信息

‘integer division or modulo by zero’

  • repr(e)

给出较全的异常信息,包括异常信息的类型,如1/0的异常信息

“ZeroDivisionError(‘integer division or modulo by zero’,)”

  • e.message

获得的信息同str(e)

  • 采用traceback模块

需要导入traceback模块,此时获取的信息最全,与python命令行运行程序出现错误信息一致。使用traceback.print_exc()打印异常信息到标准错误,就像没有获取一样,或者使用traceback.format_exc()将同样的输出获取为字符串。你可以向这些函数传递各种各样的参数来限制输出,或者重新打印到像文件类型的对象

注意:

在 Python 3 Exception 的 except 子句中,不支持使用逗号 ,分隔 Exception 和 e,所以需要采用 as 关键词进行替换

#以 1/0 异常处理为例
try:
    1/0
except Exception as e:
    print('str(Exception):\t', e.message)
    print('str(e):\t\t', str(e))
    print('repr(e):\t', repr(e))

与 Python 2 Exception 类相比,Python 3 Exception 类没有 message 成员变量。针对这个问题,可以采用 sys.exc_info()方法获取得到相关的异常信息。 sys.exc_info方法可以获取 except 子句正在处理的异常,其返回值为一个tuple类型的三元组(exc_type, exc_value, exc_traceback),其中,exc_type为获取到的异常类型;exc_value为该异常类型对象;exc_traceback为一个 traceback 对象,包含异常最初发生的调用栈信息。

程序中的变量 e 和 exc_value 是同一个异常类型实例对象

27. with关键字

对于系统资源如文件、数据库连接、socket 而言,应用程序打开这些资源并执行完业务逻辑之后,必须做的一件事就是要关闭(断开)该资源,with关键字就是用来自动关闭资源的

with语句实质上是一个上下文管理器,with语句后的对象都会有__enter__() __exit__() 方法。在进入到上下文时,会自动调用__enter__() 方法,程序正常执行完成,或者出现异常中断的时候,都会调用__exit__() 方法

用with关键字打开文件

with open('路径','w') as 变量名:

28. 高级装饰器

29. 迭代器

迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不能后退

29.1. 迭代对象(Iterable)

  • 本质

一个具备了__iter__ 方法的对象,就是一个可迭代对象

  • 判断

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

29.2. 迭代器(Iterator)

  • 本质

一个实现了__iter__方法和__next__方法的对象,就是迭代器

  • 判断

调用一个对象的__iter__ 方法,或者调用iter()内置函数,可以获取到一个可迭代对象的迭代器,然后使用isinstance()判断一个对象是否是 Iterator 对象

30. 生成器

生成器是一类特殊的迭代器

31. 时间戳转日期

import time
 
# 获得当前时间时间戳
now = int(time.time())
#转换为其他日期格式,如:"%Y-%m-%d %H:%M:%S"
timeArray = time.localtime(now)
otherStyleTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
print(otherStyleTime)

32. linux下的py

32.1. 代码执行

  • 用python指令执行
  • 用shebang,Shebang(也称为Hashbang)是一个由井号和叹号构成的字符序列#!,shebang符号可以在脚本内部指定解释器路径
#! /usr/bin/python
print 'hahah'

先赋予这个脚本文件执行权限
然后`./脚本名称`即可运行

本站总访问量