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)	#直接访问私有属性
  • 定义方法访问

可以通过定义get 和 set 方法来实现访问私有

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'

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

本站总访问量次