目录
1、环境搭建
建议直接安装 PyCharm (Community Edition) + Python3.x版本,前者是一个很好用的编译器,后者是Python的运行环境之类的,安装过程没什么好说的很普通,安装参考https://zhinan.sogou.com/guide/detail/?id=316513356341.环境配置相对简单,网上也有很多教程,这里就不一一赘述了.
PyCharm 的下载地址:http://www.jetbrains.com/pycharm/download/#section=windows
Python下载地址:https://www.python.org/downloads/windows/
2、标识符
- 第一个字符必须是字母表中字母或下划线 _ 。
- 标识符的其他的部分由字母、数字和下划线组成。
- 标识符对大小写敏感。
3、python保留字
保留字即关键字,我们不能把它们用作任何标识符名称。Python 的标准库提供了一个 keyword 模块,可以输出当前版本的所有关键字:
>>> import keyword
>>> keyword.kwlist
['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
4、注释和空行
- 单行注释:#
- 多行注释:多行注释可以用多个 # 号,还有 ''' 和 """:
- 无需; 用空行隔断语句,若一行需要多条语句则用;隔开
#!/usr/bin/python3
# 第一个注释
# 第二个注释
'''
第三注释
第四注释
'''
"""
第五注释
第六注释
"""
print ("Hello, xb!")
5、行与缩进
与C++和JAVA不一样,python使用缩进来表示代码块,不需要使用大括号 {} 。缩进的空格数是可变的,但是同一个代码块的语句必须包含相同的缩进空格数。实例如下:
if 0 :
print('00')
print('11') #输出的是11
6、多行语句
Python 通常是一行写完一条语句,但如果语句很长,我们可以使用反斜杠(\)来实现多行语句,例如:
total = item_one + \
item_two + \
item_three
在 [], {}, 或 () 中的多行语句,则不需要使用反斜杠(\),例如:
total = ['item_one', 'item_two', 'item_three',
'item_four', 'item_five']
7、声明变量
- Python无需像Java和C++一样在声明变量前需要知道类型,每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。变量没有类型. 分配内存后才有,如:
xiaobin = 1
print(xiaobin) #输出 1
- 等号(=)赋值
- 多变量赋值如下:
a = b = c = 1 #a = 1;b = 1; c = 1
a, b, c = 1, 2, "ranxia" #a = 1;b = 2; c ="ranxia"
- 一个变量可以通过赋值指向不同类型的对象。
- 在数值混合计算时,Python会把整型转换成为浮点数。
8、标准数据类型
Python3 中有六个标准的数据类型:
- Number(数字)
- String(字符串)
- List(列表)
- Tuple(元组)
- Set(集合)
- Dictionary(字典)
在这六种类型中
不可变数据(3 个) | 可变数据(3 个) |
Number(数字)、String(字符串)、Tuple(元组) | List(列表)、Dictionary(字典)、Set(集合) |
注:del var 都能起到删除的作用
变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。
8.1 Number(数字)
python中数字有四种类型:整数、布尔型、浮点数和复数。
- int (整数),:如 1, 只有一种整数类型 int,表示为长整型.
- bool (布尔):如 True。
- float (浮点数):如 1.23、3E-2
- complex (复数),:如 1 + 2j(complex(1,2)),1.1 + 2.2j
内置的 type() 函数和 isinstance() 可以用来查询变量所指的对象类型。
ranxia = 228 #当变量被赋值时,Number对象即被创建
print(type(ranxia)) #<class 'int'>
print(isinstance(ranxia,int)) #True
isinstance 和 type 的区别在于:
- type()不会认为子类是一种父类类型。
- isinstance()会认为子类是一种父类类型。
class X :
pass
class R(X):
pass
print(isinstance(R(),X)) #True
print(type(R()) == X) #False
您可以通过使用del语句删除单个或多个对象。例如:
del xiao, x1
数值运算:
print(1 + 1) #加法 2
print(5.2 - 2) #减法 3.2
print(3 * 7) #乘法 21
print(2 / 4) #除法,取浮点数0.5
print(2 // 4) #除法,取整数 0
print(5 % 2) #取余 1
print(2 ** 3) #乘方,8
数学函数:
函数 | 返回值 ( 描述 ) |
---|---|
abs(x) | 返回数字的绝对值,如abs(-10) 返回 10 |
ceil(x) | 返回数字的上入整数,如math.ceil(4.1) 返回 5 |
cmp(x, y) |
如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1。 Python 3 已废弃,使用 (x>y)-(x<y) 替换。 |
exp(x) | 返回e的x次幂(ex),如math.exp(1) 返回2.718281828459045 |
fabs(x) | 返回数字的绝对值,如math.fabs(-10) 返回10.0 |
floor(x) | 返回数字的下舍整数,如math.floor(4.9)返回 4 |
log(x) | 如math.log(math.e)返回1.0,math.log(100,10)返回2.0 |
log10(x) | 返回以10为基数的x的对数,如math.log10(100)返回 2.0 |
max(x1, x2,...) | 返回给定参数的最大值,参数可以为序列。 |
min(x1, x2,...) | 返回给定参数的最小值,参数可以为序列。 |
modf(x) | 返回x的整数部分与小数部分,两部分的数值符号与x相同,整数部分以浮点型表示。 |
pow(x, y) | x**y 运算后的值。 |
round(x [,n]) | 返回浮点数x的四舍五入值,如给出n值,则代表舍入到小数点后的位数。 |
sqrt(x) | 返回数字x的平方根。 |
随机数函数:
随机数可以用于数学,游戏,安全等领域中,还经常被嵌入到算法中,用以提高算法效率,并提高程序的安全性。
函数 | 描述 |
---|---|
choice(seq) | 从序列的元素中随机挑选一个元素,比如random.choice(range(10)),从0到9中随机挑选一个整数。 |
randrange ([start,] stop [,step]) | 从指定范围内,按指定基数递增的集合中获取一个随机数,基数缺省值为1 |
random() | 随机生成下一个实数,它在[0,1)范围内。 |
seed([x]) | 改变随机数生成器的种子seed。如果你不了解其原理,你不必特别去设定seed,Python会帮你选择seed。 |
shuffle(lst) | 将序列的所有元素随机排序 |
uniform(x, y) | 随机生成下一个实数,它在[x,y]范围内。 |
三角函数:
函数 | 描述 |
---|---|
acos(x) | 返回x的反余弦弧度值。 |
asin(x) | 返回x的反正弦弧度值。 |
atan(x) | 返回x的反正切弧度值。 |
atan2(y, x) | 返回给定的 X 及 Y 坐标值的反正切值。 |
cos(x) | 返回x的弧度的余弦值。 |
hypot(x, y) | 返回欧几里德范数 sqrt(x*x + y*y)。 |
sin(x) | 返回的x弧度的正弦值。 |
tan(x) | 返回x弧度的正切值。 |
degrees(x) | 将弧度转换为角度,如degrees(math.pi/2) , 返回90.0 |
radians(x) | 将角度转换为弧度 |
数学常量:
常量 | 描述 |
---|---|
pi | 数学常量 pi(圆周率,一般以π来表示) |
e | 数学常量 e,e即自然常数(自然常数)。 |
数字类型转换:
-
int(x) 将x转换为一个整数。
-
float(x) 将x转换到一个浮点数。
-
complex(x) 将x转换到一个复数,实数部分为 x,虚数部分为 0。
-
complex(x, y) 将 x 和 y 转换到一个复数,实数部分为 x,虚数部分为 y。x 和 y 是数字表达式。
8.2 字符串(String)
- python中单引号和双引号使用完全相同。
- 使用三引号('''或""")可以指定一个多行字符串,或者使用反斜杠(\)可以作为续行符,表示下一行是上一行的延续
- 在 print 打印的时候双引号与单引号都可以当做定界符使用,且可以嵌套。被嵌套的会被解释成为标点符号,反之一样。
word = '字符串'
sentence = "这是一个句子。"
paragraph = """这是一个段落,
可以由多行组成"""
print(word) #字符串
print(sentence) #这是一个句子。
print(paragraph) #这是一个段落,
#可以由多行组成
print("xiao'bin'") #xiao'bin'
print("aaaaaaaaaa"\
"11111") #aaaaaaaaaa11111
- 转义符 '\'
- 反斜杠可以用来转义,使用r可以让反斜杠不发生转义。。 如 r"this is a line with \n" 则\n会显示,并不是换行。
- 字符串可以用 + 运算符连接在一起,用 * 运算符重复。
- Python 中的字符串有两种索引方式,从左往右以 0 开始,从右往左以 -1 开始。
- 与 C 字符串不同的是,Python 字符串不能被改变。向一个索引位置赋值,比如word[0] = 'm'会导致错误。
- Python 没有单独的字符类型,一个字符就是长度为 1 的字符串。
- 字符串的截取的语法格式如下:变量[头下标:尾下标:步长]
- 字符串截取可以接收第三个参数,参数作用是截取的步长,以下实例在索引 1 到索引 4 的位置并设置为步长为 2(间隔一个位置)来截取字符串,如果第三个参数为负数表示逆向读取,如翻转列表:
str = 'ranxia'
print(str) # ranxia
print(str[0:-1]) # ranxia
print(str[0]) # r
print(str[2:5]) # nxi
print(str[2:]) # nxia
print(str * 2) # ranxiaranxia *表重复
print(str + '你好') # ranxia你好 +号表连接
print('ran\nxia') # ran
# xia
print(r'ran\nxia') # ranxia
xiaobin = "123456789"
print(xiaobin[1:8:2]) #2468
print(xiaobin[-1: :-1]) #987654321
转义字符:
在需要在字符中使用特殊字符时,python用反斜杠(\)转义字符。如下表:
转义字符 | 描述 |
---|---|
\(在行尾时) | 续行符 |
\\ | 反斜杠符号 |
\' | 单引号 |
\" | 双引号 |
\a | 响铃 |
\b | 退格(Backspace) |
\000 | 空 |
\n | 换行 |
\v | 纵向制表符 |
\t | 横向制表符 |
\r | 回车 |
\f | 换页 |
\oyy | 八进制数,yy 代表的字符,例如:\o12 代表换行,其中 o 是字母,不是数字 0。 |
\xyy | 十六进制数,yy代表的字符,例如:\x0a代表换行 |
\other | 其它的字符以普通格式输出 |
字符串运算符:
下表实例变量a值为字符串 "Hello",b变量值为 "Python":
操作符 | 描述 |
---|---|
+ | 字符串连接 |
* | 重复输出字符串 |
[] | 通过索引获取字符串中字符 |
[ : ] | 截取字符串中的一部分,遵循左闭右开原则,str[0,2] 是不包含第 3 个字符的。 |
in | 成员运算符 - 如果字符串中包含给定的字符返回 True |
not in | 成员运算符 - 如果字符串中不包含给定的字符返回 True |
r/R | 原始字符串 - 原始字符串:所有的字符串都是直接按照字面的意思来使用,没有转义特殊或不能打印的字符。 原始字符串除在字符串的第一个引号前加上字母 r(可以大小写)以外,与普通字符串有着几乎完全相同的语法。 |
% | 格式字符串 |
%字符串格式化沿用了C语言的风格,建议使用format():
print("我喜欢%s已经%d年了"%("冉冉",16)) #我喜欢冉冉已经16年了
print("我喜欢{}已经{}年了".format("冉冉",16)) #我喜欢冉冉已经16年了
print("我喜欢{1}已经{0}年了".format(16,"冉冉")) #我喜欢冉冉已经16年了 #这种方式可以指定顺序
字符串格式化符号:
%c | 格式化字符及其ASCII码 |
%s | 格式化字符串 |
%d | 格式化整数 |
%u | 格式化无符号整型 |
%o | 格式化无符号八进制数 |
%x | 格式化无符号十六进制数 |
%X | 格式化无符号十六进制数(大写) |
%f | 格式化浮点数字,可指定小数点后的精度 |
%e | 用科学计数法格式化浮点数 |
%E | 作用同%e,用科学计数法格式化浮点数 |
%g | %f和%e的简写 |
%G | %f 和 %E 的简写 |
%p | 用十六进制数格式化变量的地址 |
格式化操作符辅助指令:
* | 定义宽度或者小数点精度 |
- | 用做左对齐 |
+ | 在正数前面显示加号( + ) |
<sp> | 在正数前面显示空格 |
# | 在八进制数前面显示零('0'),在十六进制前面显示'0x'或者'0X'(取决于用的是'x'还是'X') |
0 | 显示的数字前面填充'0'而不是默认的空格 |
% | '%%'输出一个单一的'%' |
(var) | 映射变量(字典参数) |
m.n. | m 是显示的最小总宽度,n 是小数点后的位数(如果可用的话) |
字符串内建函数:
序号 | 方法及描述 |
---|---|
1 | capitalize() |
2 | 返回一个指定的宽度 width 居中的字符串,fillchar 为填充的字符,默认为空格。 |
3 | count(str, beg= 0,end=len(string)) 返回 str 在 string 里面出现的次数,如果 beg 或者 end 指定则返回指定范围内 str 出现的次数 |
4 | bytes.decode(encoding="utf-8", errors="strict") Python3 中没有 decode 方法,但我们可以使用 bytes 对象的 decode() 方法来解码给定的 bytes 对象,这个 bytes 对象可以由 str.encode() 来编码返回。 |
5 | encode(encoding='UTF-8',errors='strict') 以 encoding 指定的编码格式编码字符串,如果出错默认报一个ValueError 的异常,除非 errors 指定的是'ignore'或者'replace' |
6 | endswith(suffix, beg=0, end=len(string)) |
7 | 把字符串 string 中的 tab 符号转为空格,tab 符号默认的空格数是 8 。 |
8 | find(str, beg=0, end=len(string)) 检测 str 是否包含在字符串中,如果指定范围 beg 和 end ,则检查是否包含在指定范围内,如果包含返回开始的索引值,否则返回-1 |
9 | index(str, beg=0, end=len(string)) 跟find()方法一样,只不过如果str不在字符串中会报一个异常. |
10 | 如果字符串至少有一个字符并且所有字符都是字母或数字则返 回 True,否则返回 False |
11 | 如果字符串至少有一个字符并且所有字符都是字母则返回 True, 否则返回 False |
12 | 如果字符串只包含数字则返回 True 否则返回 False.. |
13 | 如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写,则返回 True,否则返回 False |
14 | 如果字符串中只包含数字字符,则返回 True,否则返回 False |
15 | 如果字符串中只包含空白,则返回 True,否则返回 False. |
16 | 如果字符串是标题化的(见 title())则返回 True,否则返回 False |
17 | 如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是大写,则返回 True,否则返回 False |
18 | 以指定字符串作为分隔符,将 seq 中所有的元素(的字符串表示)合并为一个新的字符串 |
19 | 返回字符串长度 |
20 | 返回一个原字符串左对齐,并使用 fillchar 填充至长度 width 的新字符串,fillchar 默认为空格。 |
21 | 转换字符串中所有大写字符为小写. |
22 | 截掉字符串左边的空格或指定字符。 |
23 | 创建字符映射的转换表,对于接受两个参数的最简单的调用方式,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标。 |
24 | 返回字符串 str 中最大的字母。 |
25 | 返回字符串 str 中最小的字母。 |
26 | 把 将字符串中的 str1 替换成 str2,如果 max 指定,则替换不超过 max 次。 |
27 | rfind(str, beg=0,end=len(string)) 类似于 find()函数,不过是从右边开始查找. |
28 | rindex( str, beg=0, end=len(string)) 类似于 index(),不过是从右边开始. |
29 | 返回一个原字符串右对齐,并使用fillchar(默认空格)填充至长度 width 的新字符串 |
30 | 删除字符串字符串末尾的空格. |
31 | split(str="", num=string.count(str)) num=string.count(str)) 以 str 为分隔符截取字符串,如果 num 有指定值,则仅截取 num+1 个子字符串 |
32 | 按照行('\r', '\r\n', \n')分隔,返回一个包含各行作为元素的列表,如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符。 |
33 | startswith(substr, beg=0,end=len(string)) 检查字符串是否是以指定子字符串 substr 开头,是则返回 True,否则返回 False。如果beg 和 end 指定值,则在指定范围内检查。 |
34 | 在字符串上执行 lstrip()和 rstrip() |
35 | 将字符串中大写转换为小写,小写转换为大写 |
36 | 返回"标题化"的字符串,就是说所有单词都是以大写开始,其余字母均为小写(见 istitle()) |
37 | translate(table, deletechars="") 根据 str 给出的表(包含 256 个字符)转换 string 的字符, 要过滤掉的字符放到 deletechars 参数中 |
38 | 转换字符串中的小写字母为大写 |
39 | 返回长度为 width 的字符串,原字符串右对齐,前面填充0 |
40 | 检查字符串是否只包含十进制字符,如果是返回 true,否则返回 false。 |
8.3 List(列表)
- 列表可以完成大多数集合类的数据结构实现。列表中元素的类型可以不相同,它支持数字,字符串甚至可以包含列表(所谓嵌套)。
- 列表是写在方括号 [] 之间、用逗号分隔开的元素列表。
- 和字符串一样,列表同样可以被索引和截取,列表被截取后返回一个包含所需元素的新列表。
- del 删除某一项
- 列表截取的语法格式:变量[头下标:尾下标].
List的一些操作如下(与String类似):
xiaobin = ["ranxia", "0228", 1011, 0.228]
test = ["hello world!"]
print(xiaobin) # ['ranxia', '0228', 1011, 0.228]
print(xiaobin[0]) # ranxia
print(xiaobin[1:3]) # ['0228', 1011]
print(xiaobin[2:]) # [1011, 0.228]
print(xiaobin * 2) # ['ranxia', '0228', 1011, 0.228, 'ranxia', '0228', 1011, 0.228]
print(xiaobin +test) # ['ranxia', '0228', 1011, 0.228, 'hello world!']
xiaoxiao = ["123",123]
del xiaoxiao[0]
print(xiaoxiao) #[123]
- 与String不一样的是,列表中的元素是可以改变的:
xiaobin[2] = "love"
print(xiaobin) #['ranxia', '0228', 'love', 0.228]
- 与String类似,列表截取可以接收第三个参数,参数作用是截取的步长,以下实例在索引 1 到索引 4 的位置并设置为步长为 2(间隔一个位置)来截取字符串:
xiaobin = ['1','2','3','4','5','6','7','8','9']
print(xiaobin[1:8:2]) #['2', '4', '6', '8']
如果第三个参数为负数表示逆向读取,如翻转列表:
xiaobin = ['1','2','3','4','5','6','7','8','9']
print(xiaobin[-1: :-1]) #['9', '8', '7', '6', '5', '4', '3', '2', '1']
列表脚本操作符:
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 | 迭代 |
列表函数&方法:
常用函数:
序号 | 函数 |
---|---|
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([index=-1]) 移除列表中的一个元素(默认最后一个元素),并且返回该元素的值 |
7 | list.remove(obj) 移除列表中某个值的第一个匹配项 |
8 | list.reverse() 反向列表中元素 |
9 | list.sort( key=None, reverse=False) 对原列表进行排序 |
10 | list.clear() 清空列表 |
11 | list.copy() 复制列表 |
这些方法可以使得列表等结构可以当做数据结构使用,比如列表(List当做堆栈、队列、推导式使用),具体在这就不深究了.
8.4 Tuple(元组)
string、list 和 tuple 都属于 sequence(序列),元组(tuple)与列表类似,对数据项的操作这里就不一一赘述了,不同之处如下:
- 元组的元素不能修改,但可以对元组进行连接组合元组合,写在小括号 () 里,元素之间也用逗号隔开。
- 虽然tuple的元素不可改变,但它可以包含可变的对象,比如list列表。
- 元组中的元素值是不允许删除的,但可以使用del语句来删除整个元组.
- 构造包含 0 个或 1 个元素的元组比较特殊,所以有一些额外的语法规则:
tup1 = () # 空元组
tup2 = (20,) # 一个元素,需要在元素后添加逗号
内置函数:
序号 | 方法及描述 | 实例 |
---|---|---|
1 | len(tuple) 计算元组元素个数。 |
|
2 | max(tuple) 返回元组中元素最大值。 |
|
3 | min(tuple) 返回元组中元素最小值。 |
|
4 | tuple(seq) 将列表转换为元组。 |
|
8.5 Set(集合)
- 集合(set)是由一个或数个不同或相同的整体组成的,构成集合的事物或对象称作元素或是成员。
- 基本功能是进行成员关系测试和删除重复元素(不能包含重复元素)。
- 可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典
xiaobin = set(["ranxia",111,111]) #xiaobin = {"ranxia",111,111}
print(xiaobin) #{'ranxia', 111} 重复的元素会被自动屏蔽掉
#成员测试
if "ranxia" in xiaobin:
print("ranxia 在集合xiaobin中") # ranxia 在集合xiaobin中
else:
print("ranxia 不在集合xiaobin中")
- 集合还可以用来集合运算
xiaobin = set("xiaobin") #会把字符串中的每一个值单独作为一个元素
print(xiaobin) #{'a', 'b', 'x', 'o', 'n', 'i'}
test = set("xiao")
print(xiaobin - test) # 差集 {'n', 'b'}
print(xiaobin | test) # 并集 {'o', 'n', 'x', 'i', 'a', 'b'}
print(xiaobin & test) # 交集 {'o', 'x', 'a', 'i'}
print(xiaobin ^ test ) # 二者不同时存在的元素 {'n', 'b'}
内置方法完整列表:
方法 | 描述 |
---|---|
add() | 为集合添加元素 |
clear() | 移除集合中的所有元素 |
copy() | 拷贝一个集合 |
difference() | 返回多个集合的差集 |
difference_update() | 移除集合中的元素,该元素在指定的集合也存在。 |
discard() | 删除集合中指定的元素 |
intersection() | 返回集合的交集 |
intersection_update() | 返回集合的交集。 |
isdisjoint() | 判断两个集合是否包含相同的元素,如果没有返回 True,否则返回 False。 |
issubset() | 判断指定集合是否为该方法参数集合的子集。 |
issuperset() | 判断该方法的参数集合是否为指定集合的子集 |
pop() | 随机移除元素 |
remove() | 移除指定元素 |
symmetric_difference() | 返回两个集合中不重复的元素集合。 |
symmetric_difference_update() | 移除当前集合中在另外一个指定集合相同的元素,并将另外一个指定集合中不同的元素插入到当前集合中。 |
union() | 返回两个集合的并集 |
update() | 给集合添加元素 |
8.6 Dictionary(字典)
和Java中的Map类似.
- 列表是有序的对象集合,字典是无序的对象集合。两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取。
- 字典是一种映射类型,字典用 { } 标识,也可以用构造函数 dict() 直接通过键值对构造它是一个无序的 键(key) : 值(value) 的集合。
- 键(key)必须使用不可变类型,所以可以用数字,字符串或元组充当,而用列表就不行
- 在同一个字典中,键(key)必须是唯一的,创建时如果同一个键被赋值两次,则只有后一个值会被记住.
xiaobin = {}
xiaobin["lover"] = "ranxia"
xiaobin[520] = "冉冉"
print(xiaobin["lover"]) #ranxia
print(xiaobin[520]) #冉冉
###另一种方式
xiaobin = {"lover" : "冉冉", 520:"ranxia"}
print(xiaobin) #{'lover': '冉冉', 520: 'ranxia'}
print(xiaobin.keys()) #dict_keys(['lover', 520]) 输出所以键
print(xiaobin.values()) #dict_values(['冉冉', 'ranxia']) 输出说有值
##构造函数 dict()
xiaobin = dict([("lover","冉冉"),(520,"ranxia")])
print(xiaobin) #{'lover': '冉冉', 520: 'ranxia'}
内置函数&方法:
常见内置函数:
序号 | 函数及描述 | 实例 |
---|---|---|
1 | len(dict) 计算字典元素个数,即键的总数。 |
|
2 | str(dict) 输出字典,以可打印的字符串表示。 |
|
3 | type(variable) 返回输入的变量类型,如果变量是字典就返回字典类型。 |
|
Python字典还包含了以下内置方法:
序号 | 函数及描述 |
---|---|
1 | radiansdict.clear() 删除字典内所有元素 |
2 | radiansdict.copy() 返回一个字典的浅复制 |
3 | radiansdict.fromkeys() 创建一个新字典,以序列seq中元素做字典的键,val为字典所有键对应的初始值 |
4 | radiansdict.get(key, default=None) 返回指定键的值,如果值不在字典中返回default值 |
5 | key in dict 如果键在字典dict里返回true,否则返回false |
6 | radiansdict.items() 以列表返回可遍历的(键, 值) 元组数组 |
7 | radiansdict.keys() 返回一个迭代器,可以使用 list() 来转换为列表 |
8 | radiansdict.setdefault(key, default=None) 和get()类似, 但如果键不存在于字典中,将会添加键并将值设为default |
9 | radiansdict.update(dict2) 把字典dict2的键/值对更新到dict里 |
10 | radiansdict.values() 返回一个迭代器,可以使用 list() 来转换为列表 |
11 | pop(key[,default]) 删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。 否则,返回default值。 |
12 | popitem() 随机返回并删除字典中的一对键和值(一般删除末尾对)。 |
8.7 数据类型转换
函数 | 描述 |
---|---|
int(x,base) | 将x转换为一个整数,x是数字或者字符串,base是转换进制,如int(x, base=10)转为十进制 |
float(x) | 将x转换到一个浮点数 |
complex(real,imag) | complex() 函数用于创建一个值为 real + imag * j 的复数或者转化一个字符串或数为复数。如果第一个参数为字符串,则不需要指定第二个参数。如:complex(1, 2) --->1+2j |
str(x) | 将对象 x 转换为字符串 |
repr(x) | 将对象 x 转换为表达式字符串,函数str() 用于将值转化为适于人阅读的形式,而repr() 转化为供解释器读取的形式。如:print(repr("ranxia"))---->'ranxia' |
eval(str) | 用来计算在字符串中的有效Python表达式,并返回一个对象,x = 7 , eval( '3 * x' )-----> 21 |
tuple(s) | 将序列 s 转换为一个元组 |
将序列 s 转换为一个列表 |
|
转换为可变集合 |
|
创建一个字典。d 必须是一个 (key, value)元组序列。 |
|
转换为不可变集合 |
|
将一个整数转换为一个字符 |
|
将一个字符转换为它的整数值 |
|
将一个整数转换为一个十六进制字符串 |
|
将一个整数转换为一个八进制字符串 |
9、输入
读取键盘输入-input():
ranxia = input("请输入:") #请输入:love ranxia
print(ranxia) #love ranxia
10、输出
Python两种输出值的方式: 表达式语句和 print() 函数。
print():
ranxia = "love"
xiaobin = "xiao"
print(ranxia) #love
print(xiaobin) #xiao
print("-----------")
print(ranxia,end=" ")
print(xiaobin,end=" ") #love xiao
如果你希望输出的形式更加多样,可以使用 str.format() 函数来格式化输出值。
如果你希望将输出的值转成字符串,可以使用 repr() 或 str() 函数来实现。
- str(): 函数返回一个用户易读的表达形式。
- repr(): 产生一个解释器易读的表达形式。
>>> s = 'Hello, Runoob'
>>> str(s)
'Hello, Runoob'
>>> repr(s)
"'Hello, Runoob'"
>>> str(1/7)
'0.14285714285714285'
>>> x = 10 * 3.25
>>> y = 200 * 200
>>> s = 'x 的值为: ' + repr(x) + ', y 的值为:' + repr(y) + '...'
>>> print(s)
x 的值为: 32.5, y 的值为:40000...
>>> # repr() 函数可以转义字符串中的特殊字符
... hello = 'hello, runoob\n'
>>> hellos = repr(hello)
>>> print(hellos)
'hello, runoob\n'
>>> # repr() 的参数可以是 Python 的任何对象
... repr((x, y, ('Google', 'Runoob')))
"(32.5, 40000, ('Google', 'Runoob'))"
str.format() 的基本使用如下:
#旧式格式化输出
print("我喜欢%s已经%d年了"%("冉冉",16)) #我喜欢冉冉已经16年了
#新式格式化输出
print("我喜欢{}已经{}年了".format("冉冉",16)) #我喜欢冉冉已经16年了
print("我喜欢{1}已经{0}年了".format(16,"冉冉")) #我喜欢冉冉已经16年了 #这种方式可以指定顺序
11、import
在 python 用 import 或者 from...import 来导入相应的模块。
- 将整个模块(somemodule)导入,格式为: import somemodule
- 从某个模块中导入某个函数,格式为: from somemodule import somefunction
- 从某个模块中导入多个函数,格式为: from somemodule import firstfunc, secondfunc, thirdfunc
- 将某个模块中的全部函数导入,格式为: from somemodule import *
- import......as ----->import A as B,给予A库一个B的别称,帮助记忆
12、运算符
- 算术运算符
- 比较运算符
- 赋值运算符
- 逻辑运算符
- 位运算符
- 成员运算符
- 身份运算符
算术运算符 :
以下假设变量a为10,变量b为21:
运算符 | 描述 | 实例 |
---|---|---|
+ | 加 - 两个对象相加 | a + b 输出结果 31 |
- | 减 - 得到负数或是一个数减去另一个数 | a - b 输出结果 -11 |
* | 乘 - 两个数相乘或是返回一个被重复若干次的字符串 | a * b 输出结果 210 |
/ | 除 - x 除以 y | b / a 输出结果 2.1 |
% | 取模 - 返回除法的余数 | b % a 输出结果 1 |
** | 幂 - 返回x的y次幂 | a**b 为10的21次方 |
// | 取整除 - 向下取接近除数的整数 | |
比较运算符:
以下假设变量a为10,变量b为20:
运算符 | 描述 | 实例 |
---|---|---|
== | 等于 - 比较对象是否相等 | (a == b) 返回 False。 |
!= | 不等于 - 比较两个对象是否不相等 | (a != b) 返回 True。 |
> | 大于 - 返回x是否大于y | (a > b) 返回 False。 |
< | 小于 - 返回x是否小于y。所有比较运算符返回1表示真,返回0表示假。这分别与特殊的变量True和False等价。注意,这些变量名的大写。 | (a < b) 返回 True。 |
>= | 大于等于 - 返回x是否大于等于y。 | (a >= b) 返回 False。 |
<= | 小于等于 - 返回x是否小于等于y。 | (a <= b) 返回 True。 |
赋值运算符:
以下假设变量a为10,变量b为20:
运算符 | 描述 | 实例 |
---|---|---|
= | 简单的赋值运算符 | c = a + b 将 a + b 的运算结果赋值为 c |
+= | 加法赋值运算符 | c += a 等效于 c = c + a |
-= | 减法赋值运算符 | c -= a 等效于 c = c - a |
*= | 乘法赋值运算符 | c *= a 等效于 c = c * a |
/= | 除法赋值运算符 | c /= a 等效于 c = c / a |
%= | 取模赋值运算符 | c %= a 等效于 c = c % a |
**= | 幂赋值运算符 | c **= a 等效于 c = c ** a |
//= | 取整除赋值运算符 | c //= a 等效于 c = c // a |
位运算符:
按位运算符是把数字看作二进制来进行计算的。下表中变量 a 为 60(0011 1100),b 为 13(0000 1101)
运算符 | 描述 | 实例 |
---|---|---|
& | 按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0 | (a & b) 输出结果 12 ,二进制解释: 0000 1100 |
| | 按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。 | (a | b) 输出结果 61 ,二进制解释: 0011 1101 |
^ | 按位异或运算符:当两对应的二进位相异时,结果为1 | (a ^ b) 输出结果 49 ,二进制解释: 0011 0001 |
~ | 按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1。~x类似于 -x-1 | (~a ) 输出结果 -61 ,二进制解释: 1100 0011, 在一个有符号二进制数的补码形式。 |
<< | 左移动运算符:运算数的各二进位全部左移若干位,由"<<"右边的数指定移动的位数,高位丢弃,低位补0。 | a << 2 输出结果 240 ,二进制解释: 1111 0000 |
>> | 右移动运算符:把">>"左边的运算数的各二进位全部右移若干位,">>"右边的数指定移动的位数 | a >> 2 输出结果 15 ,二进制解释: 0000 1111 |
逻辑运算符:
假设变量 a 为 10, b为 20: 相当于C语言的 && ,|| ,!.
运算符 | 逻辑表达式 | 描述 | 实例 |
---|---|---|---|
and | x and y | 布尔"与" - 如果 x 为 False,x and y 返回 False,否则它返回 y 的计算值。 | (a and b) 返回 20。 |
or | x or y | 布尔"或" - 如果 x 是 True,它返回 x 的值,否则它返回 y 的计算值。 | (a or b) 返回 10。 |
not | not x | 布尔"非" - 如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。 | not(a and b) 返回 False |
成员运算符:
成员运算符,成员包括字符串,列表或元组。
运算符 | 描述 | 实例 |
---|---|---|
in | 如果在指定的序列中找到值返回 True,否则返回 False。 | x 在 y 序列中 , 如果 x 在 y 序列中返回 True。 |
not in | 如果在指定的序列中没有找到值返回 True,否则返回 False。 | x 不在 y 序列中 , 如果 x 不在 y 序列中返回 True。 |
if "ranxia" in xiaobin:
print("ranxia 在集合xiaobin中") # ranxia 在集合xiaobin中
elif (111 not in xiaobin) :
print("111 在集合xiaobin中") #222 不在集合xiaobin中
身份运算符:
身份运算符用于比较两个对象的存储单元
运算符 | 描述 | 实例 |
---|---|---|
is | is 是判断两个标识符是不是引用自一个对象 | x is y, 类似 id(x) == id(y) , 如果引用的是同一个对象则返回 True,否则返回 False |
is not | is not 是判断两个标识符是不是引用自不同对象 | x is not y , 类似 id(a) != id(b)。如果引用的不是同一个对象则返回结果 True,否则返回 False。 |
注: id() 函数用于获取对象内存地址。
x1 = "xiaobin"
x2 = "xiaobin"
if x1 is x2: #换成id(x1) == id(x2)一样
print("x1和x2有相同标识") #x1和x2有相同标识
else:
print("x1和x2没有相同标识")
运算符优先级:
以下表格列出了从最高到最低优先级的所有运算符:
运算符 | 描述 |
---|---|
** | 指数 (最高优先级) |
~ + - | 按位翻转, 一元加号和减号 (最后两个的方法名为 +@ 和 -@) |
* / % // | 乘,除,取模和取整除 |
+ - | 加法减法 |
>> << | 右移,左移运算符 |
& | 位 'AND' |
^ | | 位运算符 |
<= < > >= | 比较运算符 |
<> == != | 等于运算符 |
= %= /= //= -= += *= **= | 赋值运算符 |
is is not | 身份运算符 |
in not in | 成员运算符 |
not and or | 逻辑运算符 |
13、控制结构
- 条件控制
- 循环控制
条件控制:if 语句(if – elif – else),应注意与C语言的else if区分.无switch结构
if condition_1:
statement_block_1
elif condition_2:
statement_block_2
else:
statement_block_3
循环控制:while + for
while 循环: 没有 do..while 循环。
a = 0
while a < 10:
print(a)
a += 1 #0 1 2 3 4 5 6 7 8 9
for 语句:
xiaobin = [1,2,3,4,5,6,7,8,9]
for x in xiaobin:
print(x) #1 2 3 4 5 6 7 8 9
range()函数:
是一个迭代器,range函数大多数时常出如今for循环中。在for循环中可做为索引使用。事实上它也能够出如今不论什么须要整数列表的环境中.
for x in range(5):
print(x) # 0 1 2 3 4
也可以使用range指定区间的值:
for x in range(5,10):
print(x) # 5 6 7 8 9
也可以使range以指定数字开始并指定不同的步长(可以是负数):
for x in range(0,10,2):
print(x) #0 2 4 6 8
for x in range(0,-10,-2):
print(x) #0 -2 -4 -6 -8
还可以结合range()和len()函数以遍历一个序列的索引,还可以使用range()函数来创建一个列表:list(range(5)) ------>[0, 1, 2, 3, 4]
break 和 continue :
和C语言和JAVA都一样,这里稍作叙述,新手需要细细体会:
- break 语句可以跳出 for 和 while 的循环体。如果你从 for 或 while 循环中终止,任何对应的循环 else 块将不执行。
- continue语句被用来告诉Python跳过当前循环块中的剩余语句,然后继续进行下一轮循环。
pass语句:
Python pass是空语句,是为了保持程序结构的完整性。pass 不做任何事情,一般用做占位语句.
while True:
pass
14、迭代器与生成器
14.1 迭代器
Python最强大的功能之一.
- 是访问集合元素的一种方式。
- 是一个可以记住遍历的位置的对象。
- 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
- 迭代器有两个基本的方法:iter() 和 next()。
- 字符串,列表或元组对象都可用于创建迭代器,通俗来讲,任何可以逐项地读取的对象,都做一个可迭代对象.
list = [1,2,3,4,5]
it = iter(list) #创建迭代器对象
print(next(it)) #1 输出下一个元素
print(next(it)) #2
有一点需要明确,迭代器指向的位置是元素之前的位置,其实和JAVA的ListIterator原理类似,如下图所示:
这里假设集合List由四个元素List1、List2、List3和List4组成,当使用语句it = iter(list)时,迭代器it指向的位置是上图中Iterator1指向的位置,当执行语句 next(it) 之后,迭代器指向的位置后移到上图Iterator2所指向的位置。
迭代器对象可以使用常规for语句进行遍历:
list = [5,6,7,8]
it = iter(list)
for x in it:
print(x,end=" ") #5 6 7 8
* 创建一个迭代器:
把一个类作为一个迭代器使用需要在类中实现两个方法 __iter__() 与 __next__() 。
- __iter__() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 __next__() 方法并通过 StopIteration 异常标识迭代的完成。
- __next__() 方法会返回下一个迭代器对象。
创建一个返回数字的迭代器,初始值为 1,逐步递增 1:
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
x = self.a
self.a += 1
return x
myclass = MyNumbers()
myiter = iter(myclass)
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
StopIteration:
StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,在 __next__() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代。
在 20 次迭代后停止执行:
class MyNumbers:
def __iter__(self):
self.a = 1
return self
def __next__(self):
if self.a <= 20:
x = self.a
self.a += 1
return x
else:
raise StopIteration
myclass = MyNumbers()
myiter = iter(myclass)
for x in myiter:
print(x) #输出 1 . . . 20的整数
14.2 生成器
在 Python 中,使用了 yield 的函数被称为生成器(generator)。
跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。调用一个生成器函数,返回的是一个迭代器对象(解决遍历时存储整个数列浪费内存的问题)。
更简单来说:
- 生成器是可以迭代的,但是你 只可以读取它一次 ,因为它并不把所有的值放在内存中,它是实时地生成数据:
- yield 是一个类似 return 的关键字,迭代一次遇到yield时就返回yield后面(右边)的值。重点是:下一次迭代时,从上一次迭代遇到的yield后面的代码(下一行)开始执行。
- 也可以理解为:yield就是 return 返回一个值(这个值就是生成器),并且记住这个返回的位置,下次迭代就从这个位置后(下一行)开始。
def yield_test():
print("开始...")
yield "hello ranxia"
print("测试")
test = yield_test()
print(next(test)) #开始 hello ranxia
print(next(test)) #测试
可以看到“测试”并没有被输出,这里体现了它的return性,当执行第二条print(next(test))时,输出结果为“测试”,这一次的next开始的地方是接着上一次的next停止的地方执行的,所以调用next的时候,生成器并不会从test函数的开始执行,只是接着上一步停止的地方开始,然后遇到yield后,return出要生成的数,此步就结束。
注:百度和文档很多写得很生涩,这算是个最简单的例子了,先弄懂yield的特性和工作原理再去看什么yield实现斐波那契数列之类的就简单多了.
具体可以参见这篇译文:https://pyzh.readthedocs.io/en/latest/the-python-yield-keyword-explained.html
15、函数
定义一个函数&调用函数:
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。
- 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数,参数可有可无。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
语法如下:
def 函数名(参数列表): 函数体
def test(var):
if var == "ranxia":
print("love u")
else:
print("piss off")
#调用函数
test("ranxia") #love u
python 函数的参数传递:
-
不可变类型(strings、 tuples, 、 numbers ):类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。
-
可变类型:类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响
def xx(a):
a = 1
b=2
xx(b)
print(b) # 2 可见并没有改变值
匿名函数 lambda:
意即不再使用 def 语句这样标准的形式定义一个函数。
- lambda 只是一个表达式,函数体比 def 简单很多。
- lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
- lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
- 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
语法如下:
lambda [arg1 [,arg2,.....argn]]:expression
sum = lambda x1,x2:x1+x2
print(sum(1,2)) #3
变量作用域:
变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。Python的作用域一共有4种,分别是:
- L (Local) 局部作用域
- E (Enclosing) 闭包函数外的函数中
- G (Global) 全局作用域
- B (Built-in) 内置作用域(内置函数所在模块的范围,其自身并没有放入内置作用域内,所以必须导入这个文件才能够使用它。可以使用dir查看)
import builtins
print(dir(builtins))
以 L –> E –> G –>B 的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内置中找。
全局变量和局部变量:
定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。
局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。
total = 0 # 这是一个全局变量
# 可写函数说明
def sum( arg1, arg2 ):
#返回2个参数的和."
total = arg1 + arg2 # total在这里是局部变量. #函数内是局部变量 : 30
print ("函数内是局部变量 : ", total)
return total
#调用sum函数
sum( 10, 20 )
print ("函数外是全局变量 : ", total) #函数外是全局变量 : 0
global 和 nonlocal关键字:
当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了。
num = 1
def fun1():
global num # 需要使用 global 关键字声明
print(num) # 1
num = 123
print(num) #123
fun1()
print(num) #123
如果要修改嵌套作用域(enclosing 作用域,外层非全局作用域)中的变量则需要 nonlocal 关键字了,如下实例:
def outer():
num = 10
def inner():
nonlocal num # nonlocal关键字声明
num = 100
print(num) #100
inner()
print(num) #100
outer()
16、文件(File)
读和写文件:
open() 将会返回一个 file 对象,基本语法格式如下:
open(filename, mode)
- filename:包含了你要访问的文件名称的字符串值。
- mode:决定了打开文件的模式:只读,写入,追加等。所有可取值见如下的完全列表。这个参数是非强制的,默认文件访问模式为只读(r)。
不同模式打开文件的完全列表:
模式 | 描述 |
---|---|
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
w | 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
w+ | 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
简要如下图:
模式 | r | r+ | w | w+ | a | a+ |
---|---|---|---|---|---|---|
读 | + | + | + | + | ||
写 | + | + | + | + | + | |
创建 | + | + | + | + | ||
覆盖 | + | + | ||||
指针在开始 | + | + | + | + | ||
指针在结尾 | + | + |
将字符串“I love ranxia”写入test.txt文件夹:
写入字符串
f = open("files/test.txt","w")
f.write("I love ranxia")
f.close()
#读取文件内容
f = open("files/test.txt","r")
str = f.read()
print(str) #I love ranxia
f.close() #关闭文件并释放系统的资源
pickle 模块:
- python的pickle模块实现了基本的数据序列和反序列化。
- 通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储。
- 通过pickle模块的反序列化操作,我们能够从文件中创建上一次程序保存的对象。
基本接口:
pickle.dump(obj, file, [,protocol])
有了 pickle 这个对象, 就能对 file 以读取的形式打开:
x = pickle.load(file)
注解:从 file 中读取一个字符串,并将它重构为原来的python对象。
file: 类文件对象,有read()和readline()接口。
实例 1:
import pickle
# 使用pickle模块将数据对象保存到文件
data1 = {'a': [1, 2.0, 3, 4+6j],
'b': ('string', u'Unicode string'),
'c': None}
selfref_list = [1, 2, 3]
selfref_list.append(selfref_list)
output = open('data.pkl', 'wb')
# Pickle dictionary using protocol 0.
pickle.dump(data1, output)
# Pickle the list using the highest protocol available.
pickle.dump(selfref_list, output, -1)
output.close()
实例 2:
import pprint, pickle
#使用pickle模块从文件中重构python对象
pkl_file = open('data.pkl', 'rb')
data1 = pickle.load(pkl_file)
pprint.pprint(data1)
data2 = pickle.load(pkl_file)
pprint.pprint(data2)
pkl_file.close()
常见方法:
file 对象使用 open 函数来创建,下表列出了 file 对象常用的函数:
序号 | 方法及描述 |
---|---|
1 | 关闭文件。关闭后文件不能再进行读写操作。 |
2 | 刷新文件内部缓冲,直接把内部缓冲区的数据立刻写入文件, 而不是被动的等待输出缓冲区写入。 |
3 | 返回一个整型的文件描述符(file descriptor FD 整型), 可以用在如os模块的read方法等一些底层操作上。 |
4 | 如果文件连接到一个终端设备返回 True,否则返回 False。 |
5 | Python 3 中的 File 对象不支持 next() 方法。 返回文件下一行。 |
6 | 从文件读取指定的字节数,如果未给定或为负则读取所有。 |
7 | 读取整行,包括 "\n" 字符。 |
8 | 读取所有行并返回列表,若给定sizeint>0,返回总和大约为sizeint字节的行, 实际读取值可能比 sizeint 较大, 因为需要填充缓冲区。 |
9 | 设置文件当前位置 |
10 | 返回文件当前位置。 |
11 | 从文件的首行首字符开始截断,截断文件为 size 个字符,无 size 表示从当前位置截断;截断之后后面的所有字符被删除,其中 Widnows 系统下的换行代表2个字符大小。 |
12 | 将字符串写入文件,返回的是写入的字符长度。 |
13 | 向文件写入一个序列字符串列表,如果需要换行则要自己加入每行的换行符。 |
OS 文件/目录方法:
序号 | 方法及描述 |
---|---|
1 | 检验权限模式 |
2 | 改变当前工作目录 |
3 | 设置路径的标记为数字标记。 |
4 | 更改权限 |
5 | 更改文件所有者 |
6 | 改变当前进程的根目录 |
7 | 关闭文件描述符 fd |
8 | os.closerange(fd_low, fd_high) 关闭所有文件描述符,从 fd_low (包含) 到 fd_high (不包含), 错误会忽略 |
9 | 复制文件描述符 fd |
10 | 将一个文件描述符 fd 复制到另一个 fd2 |
11 | 通过文件描述符改变当前工作目录 |
12 | 改变一个文件的访问权限,该文件由参数fd指定,参数mode是Unix下的文件访问权限。 |
13 | 修改一个文件的所有权,这个函数修改一个文件的用户ID和用户组ID,该文件由文件描述符fd指定。 |
14 | 强制将文件写入磁盘,该文件由文件描述符fd指定,但是不强制更新文件的状态信息。 |
15 | os.fdopen(fd[, mode[, bufsize]]) 通过文件描述符 fd 创建一个文件对象,并返回这个文件对象 |
16 | 返回一个打开的文件的系统配置信息。name为检索的系统配置的值,它也许是一个定义系统值的字符串,这些名字在很多标准中指定(POSIX.1, Unix 95, Unix 98, 和其它)。 |
17 | 返回文件描述符fd的状态,像stat()。 |
18 | 返回包含文件描述符fd的文件的文件系统的信息,Python 3.3 相等于 statvfs()。 |
19 | 强制将文件描述符为fd的文件写入硬盘。 |
20 | 裁剪文件描述符fd对应的文件, 所以它最大不能超过文件大小。 |
21 | 返回当前工作目录 |
22 | 返回一个当前工作目录的Unicode对象 |
23 | 如果文件描述符fd是打开的,同时与tty(-like)设备相连,则返回true, 否则False。 |
24 | 设置路径的标记为数字标记,类似 chflags(),但是没有软链接 |
25 | 修改连接文件权限 |
26 | 更改文件所有者,类似 chown,但是不追踪链接。 |
27 | 创建硬链接,名为参数 dst,指向参数 src |
28 | 返回path指定的文件夹包含的文件或文件夹的名字的列表。 |
29 | 设置文件描述符 fd当前位置为pos, how方式修改: SEEK_SET 或者 0 设置从文件开始的计算的pos; SEEK_CUR或者 1 则从当前位置计算; os.SEEK_END或者2则从文件尾部开始. 在unix,Windows中有效 |
30 | 像stat(),但是没有软链接 |
31 | 从原始的设备号中提取设备major号码 (使用stat中的st_dev或者st_rdev field)。 |
32 | 以major和minor设备号组成一个原始设备号 |
33 | 递归文件夹创建函数。像mkdir(), 但创建的所有intermediate-level文件夹需要包含子文件夹。 |
34 | 从原始的设备号中提取设备minor号码 (使用stat中的st_dev或者st_rdev field )。 |
35 | 以数字mode的mode创建一个名为path的文件夹.默认的 mode 是 0777 (八进制)。 |
36 | 创建命名管道,mode 为数字,默认为 0666 (八进制) |
37 | os.mknod(filename[, mode=0600, device]) |
38 | 打开一个文件,并且设置需要的打开选项,mode参数是可选的 |
39 | 打开一个新的伪终端对。返回 pty 和 tty的文件描述符。 |
40 | 返回相关文件的系统配置信息。 |
41 | 创建一个管道. 返回一对文件描述符(r, w) 分别为读和写 |
42 | os.popen(command[, mode[, bufsize]]) 从一个 command 打开一个管道 |
43 | 从文件描述符 fd 中读取最多 n 个字节,返回包含读取字节的字符串,文件描述符 fd对应文件已达到结尾, 返回一个空字符串。 |
44 | 返回软链接所指向的文件 |
45 | 删除路径为path的文件。如果path 是一个文件夹,将抛出OSError; 查看下面的rmdir()删除一个 directory。 |
46 | 递归删除目录。 |
47 | 重命名文件或目录,从 src 到 dst |
48 | 递归地对目录进行更名,也可以对文件进行更名。 |
49 | 删除path指定的空目录,如果目录非空,则抛出一个OSError异常。 |
50 | 获取path指定的路径的信息,功能等同于C API中的stat()系统调用。 |
51 | os.stat_float_times([newvalue]) |
52 | 获取指定路径的文件系统统计信息 |
53 | 创建一个软链接 |
54 | 返回与终端fd(一个由os.open()返回的打开的文件描述符)关联的进程组 |
55 | 设置与终端fd(一个由os.open()返回的打开的文件描述符)关联的进程组为pg。 |
56 | 返回一个字符串,它表示与文件描述符fd 关联的终端设备。如果fd 没有与终端设备关联,则引发一个异常。 |
57 | 删除文件路径 |
58 | 返回指定的path文件的访问和修改的时间。 |
59 | os.walk(top[, topdown=True[, οnerrοr=None[, followlinks=False]]]) 输出在文件夹中的文件名通过在树中游走,向上或者向下。 |
60 | 写入字符串到文件描述符 fd中. 返回实际写入的字符串长度 |
61 | 获取文件的属性信息。 |
17、错误与异常
即便Python程序的语法是正确的,在运行它的时候,也有可能发生错误。运行期检测到的错误被称为异常,比如除数为0,文件找不等。
异常处理:try-except-finally
这一部分内容和JAVA的异常处理类似:
import sys
try: #try是需要检测异常的语句块
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except OSError as err: #捕获异常并作出相应处理
print("OS error: {0}".format(err))
except ValueError:
print("Could not convert data to an integer.")
except:
print("Unexpected error:", sys.exc_info()[0])
raise
try语句按照如下方式工作;
- 首先,执行try子句(在关键字try和关键字except之间的语句)
- 如果没有异常发生,忽略except子句,try子句执行后结束。
- 如果在执行try子句的过程中发生了异常,那么try子句余下的部分将被忽略。如果异常的类型和 except 之后的名称相符,那么对应的except子句将被执行。最后执行 try 语句之后的代码。
- 如果一个异常没有与任何的except匹配,那么这个异常将会传递给上层的try中。
- 一个 try 语句可能包含多个except子句,分别来处理不同的特定的异常。最多只有一个分支会被执行。
- 处理程序将只针对对应的try子句中的异常进行处理,而不是其他的 try 的处理程序中的异常。
- 一个except子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组,例如:
- 最后一个except子句可以忽略异常的名称,它将被当作通配符使用。你可以使用这种方法打印一个错误信息,然后再次把异常抛出。
except (RuntimeError, TypeError, NameError): pass
- try except 语句还有一个可选的else子句,如果使用这个子句,那么必须放在所有的except子句之后。这个子句将在try子句没有发生任何异常的时候执行。例如:
for arg in sys.argv[1:]:
try:
f = open(arg, 'r')
except IOError:
print('cannot open', arg)
else:
print(arg, 'has', len(f.readlines()), 'lines')
f.close()
使用 else 子句比把所有的语句都放在 try 子句里面要好,这样可以避免一些意想不到的、而except又没有捕获的异常。
抛出异常:
Python 使用 raise 语句抛出一个指定的异常。例如:
>>>raise NameError('HiThere')
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: HiThere
raise 唯一的一个参数指定了要被抛出的异常。它必须是一个异常的实例或者是异常的类(也就是 Exception 的子类)。
如果你只想知道这是否抛出了一个异常,并不想去处理它,那么一个简单的 raise 语句就可以再次把它抛出。
>>>try:
raise NameError('HiThere')
except NameError:
print('An exception flew by!')
raise
An exception flew by!
Traceback (most recent call last):
File "<stdin>", line 2, in ?
NameError: HiThere
用户自定义异常:
可以通过创建一个新的异常类来拥有自己的异常。异常类继承自 Exception 类,可以直接继承,或者间接继承,例如:
>>>class MyError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
>>> try:
raise MyError(2*2)
except MyError as e:
print('My exception occurred, value:', e.value)
My exception occurred, value: 4
>>> raise MyError('oops!')
Traceback (most recent call last):
File "<stdin>", line 1, in ?
__main__.MyError: 'oops!'
在这个例子中,类 Exception 默认的 __init__() 被覆盖。当创建一个模块有可能抛出多种不同的异常时,一种通常的做法是为这个包建立一个基础异常类,然后基于这个基础类为不同的错误情况创建不同的子类:
class Error(Exception):
"""Base class for exceptions in this module."""
pass
class InputError(Error):
"""Exception raised for errors in the input.
Attributes:
expression -- input expression in which the error occurred
message -- explanation of the error
"""
def __init__(self, expression, message):
self.expression = expression
self.message = message
class TransitionError(Error):
"""Raised when an operation attempts a state transition that's not
allowed.
Attributes:
previous -- state at beginning of transition
next -- attempted new state
message -- explanation of why the specific transition is not allowed
"""
def __init__(self, previous, next, message):
self.previous = previous
self.next = next
self.message = message
注:大多数的异常的名字都以"Error"结尾,就跟标准的异常命名一样。
定义清理行为:
try 语句还有另外一个可选的子句finally,它定义了无论在任何情况下都会执行的清理行为。 例如:
>>>try:
... raise KeyboardInterrupt
... finally:
... print('Goodbye, world!')
...
Goodbye, world!
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
KeyboardInterrupt
以上例子不管 try 子句里面有没有发生异常,finally 子句都会执行。
如果一个异常在 try 子句里(或者在 except 和 else 子句里)被抛出,而又没有任何的 except 把它截住,那么这个异常会在 finally 子句执行后被抛出。
下面是一个更加复杂的例子(在同一个 try 语句里包含 except 和 finally 子句):
>>>def divide(x, y):
try:
result = x / y
except ZeroDivisionError:
print("division by zero!")
else:
print("result is", result)
finally:
print("executing finally clause")
>>> divide(2, 1)
result is 2.0
executing finally clause
>>> divide(2, 0)
division by zero!
executing finally clause
>>> divide("2", "1")
executing finally clause
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in divide
TypeError: unsupported operand type(s) for /: 'str' and 'str'
预定义的清理行为-with语句(推荐!):
一些对象定义了标准的清理行为,无论系统是否成功的使用了它,一旦不需要它了,那么这个标准的清理行为就会执行。
这面这个例子展示了尝试打开一个文件,然后把内容打印到屏幕上:
for line in open("myfile.txt"):
print(line, end="")
以上这段代码的问题是,当执行完毕后,文件会保持打开状态,并没有被关闭。
关键词 with 语句就可以保证诸如文件之类的对象在使用完之后一定会正确的执行他的清理方法:
with open("myfile.txt") as f:
for line in f:
print(line, end="")
以上这段代码执行完毕后,就算在处理过程中出问题了,文件 f 总是会关闭。当操作文件时,with获取了应用上下文,在结束时会自动执行close函数来关闭文件。其实可以把with看成if之类的控制语句,简化了try-except-finally的结构.
18、面向对象
面向工资编程的首要前提是你得先面向对象编程..
面向对象技术简介:
- 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
- 方法:类中定义的函数。
- 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
- 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
- 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
- 局部变量:定义在方法中的变量,只作用于当前实例的类。
- 实例变量:在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
- 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
- 实例化:创建一个类的实例,类的具体对象。
- 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
Python中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法。
定义一个类:
class ClassName:
<statement-1>
.
.
.
<statement-N>
访问类对象:
class R:
name = "ranxia"
def getName(self): #必须有self
return "11"
r = R()
print(r.name) #ranxia
print(r.getName()) #11
构造方法(__init__() )
类定义了 __init__() 方法,类的实例化操作会自动调用 __init__() 方法,当然, __init__() 方法可以有参数,参数通过 __init__() 传递到类的实例化操作上:
class R1:
x = ""
r = ""
__t = 0 #定义私有属性
def __init__(self,x,r):
self.x = x
self.r = r
self.__t = t #私有属性
r = R1("xiaobin","ranxia")
print(r.x + " "+ r.r) #xiaobin ranxia
self代表类的实例,而非类,类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self。代表当前对象的地址,而 self.class 则指向类。
类的方法:
在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self, 且为第一个参数,self 代表的是类的实例。
继承:
语法如下:
class DerivedClassName(BaseClassName1):
<statement-1>
.
.
.
<statement-N>
需要注意圆括号中基类的顺序,若是基类中有相同的方法名,而在子类使用时未指定,python从左至右搜索 即方法在子类中未找到时,从左到右查找基类中是否包含方法。
BaseClassName(示例中的基类名)必须与派生类定义在一个作用域内。除了类,还可以用表达式,基类定义在另一个模块中时这一点非常有用.
class DerivedClassName(modname.BaseClassName):
class XB:
name = ""
def __init__(self, name):
self.name = name
def say(self):
print("我的名字是" + self.name)
class XX(XB):
mother = ""
def __init__(self,name,mother):
XB.__init__(self,name) #调用父类构造方法
self.mother = mother
def say(self): #重写父类的say方法
print("我的名字是"+self.name+" "+"我的妈妈是"+self.mother)
xb = XB("xiaobin")
xb.say() #我的名字是xiaobin
xx = XX("xiaoxiao","ranxia")
xx.say() #我的名字是xiaoxiao 我的妈妈是ranxia
多继承:
同单继承差不多,这里就不一一赘述了,多继承的语法格式如下:
class DerivedClassName(Base1, Base2, Base3):
<statement-1>
.
.
.
<statement-N>
注意:需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索 即方法在子类中未找到时,从左到右查找父类中是否包含方法。
方法重写:
在上面的实例里已经介绍了方法重写的例子,在这里补充一下super()函数,其是用于调用父类(超类)已被子类覆盖的一个方法。语法格式如下:
super(子类名称,子类实例). 父类方法名
======>>>> super(Child,c).myMethod() #用子类对象调用父类已被覆盖的方法
类的私有属性:
__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。
类的方法:
在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数,self 代表的是类的实例。
self 的名字并不是规定死的,也可以使用 this,但是最好还是按照约定是用 self。
类的私有方法:
__private_method:两个下划线开头,声明该方法为私有方法,只能在类的内部调用 ,不能在类的外部调用。self.__private_methods。
类的私有属性实例如下:
class JustCounter:
__secretCount = 0 # 私有变量
publicCount = 0 # 公开变量
def count(self):
self.__secretCount += 1
self.publicCount += 1
print (self.__secretCount)
counter = JustCounter()
counter.count()
counter.count()
print (counter.publicCount)
print (counter.__secretCount) # 报错,实例不能访问私有变量
类的私有方法示例如下:
class Site:
def __init__(self, name, url):
self.name = name # public
self.__url = url # private
def who(self):
print('name : ', self.name)
print('url : ', self.__url)
def __foo(self): # 私有方法
print('这是私有方法')
def foo(self): # 公共方法
print('这是公共方法')
self.__foo()
x = Site('菜鸟教程', 'www.runoob.com')
x.who() # 正常输出
x.foo() # 正常输出
x.__foo() # 报错
类的专有方法:
- __init__ : 构造函数,在生成对象时调用
- __del__ : 析构函数,释放对象时使用
- __repr__ : 打印,转换
- __setitem__ : 按照索引赋值
- __getitem__: 按照索引获取值
- __len__: 获得长度
- __cmp__: 比较运算
- __call__: 函数调用
- __add__: 加运算
- __sub__: 减运算
- __mul__: 乘运算
- __truediv__: 除运算
- __mod__: 求余运算
- __pow__: 乘方
运算符重载:
Python同样支持运算符重载,我们可以对类的专有方法进行重载,实例如下:
class Vector:
def __init__(self, a, b):
self.a = a
self.b = b
def __str__(self):
return 'Vector (%d, %d)' % (self.a, self.b)
def __add__(self,other):
return Vector(self.a + other.a, self.b + other.b)
v1 = Vector(2,10)
v2 = Vector(5,-2)
print (v1 + v2) #Vector(7,8)
19、标准库
名称 | 描述 |
---|---|
os | 提供了不少与操作系统相关联的函数。 |
glob | 提供了一个函数用于从目录通配符搜索中生成文件列表: |
sys | 提供通用工具脚本经常调用命令行参数,还包括错误输出重定向和程序终止 |
rel | 为高级字符串处理提供了正则表达式工具 |
math | 模块为浮点运算提供了对底层C函数库的访问 |
random | 提供了生成随机数的工具。 |
urllib.request、 smtplib |
用于访问互联网以及处理网络通信协议。其中最简单的两个是用于处理从 urls 接收的数据的urllib.request 以及用于发送电子邮件的smtplib : |
datetime | 为日期和时间处理同时提供了简单和复杂的方法。 |
zlib,gzip,bz2,zipfile, tarfile。 | 以下模块直接支持通用的数据打包和压缩格式:zlib,gzip,bz2,zipfile,以及 tarfile。 |
timeit | 提供了一个度量不同方法之间的性能差异工具,为这些问题提供了直接答案。 |
doctest | 开发高质量软件的方法之一是为每一个函数开发测试代码,并且在开发过程中经常进行测试,该模块提供了一个工具,扫描模块并根据程序中内嵌的文档字符串执行测试。 |
花了两天基础部分差不多已经涵盖完了,至于Py的一些其他深层次的应用会在以后的过程中慢慢更新......