python数据类型
在第一遍学习python时太过于匆忙,现将python的核心基础重新学习(尚未完成总结)
介绍
-
Python 是一种解释型、面向对象、动态数据类型的高级程序设计语言。
-
Python 由 Guido van Rossum 于 1989 年底发明,第一个公开发行版发行于 1991 年。
-
像 Perl 语言一样, Python 源代码同样遵循 GPL(GNU General Public License) 协议。
-
官方宣布,2020 年 1 月 1 日, 停止 Python 2 的更新。
-
Python 2.7 被确定为最后一个 Python 2.x 版本。
基础语法
-
编码:默认情况下python3源码文件以UTF-8的编码格式,所有字符串都是 unicode 字符串
-
标识符
- 首字符以下划线或者字母开头
- 之后可以是数字、字母、下划线
- 严格区分大小写
-
保留字
-
查看保留字
import keyword keyword.kwlist
-
-
注释
- 单行注释
···
- 多行注释
'''···'''
,也可以使用双引号
- 单行注释
-
行与缩进
- 在python中使用缩进来表示代码块,缩进的空格数是可变的,但是同一个代码块的语句必须包含相同的缩进空格
-
数字类型
- int (整数), 如 1, 只有一种整数类型 int,表示为长整型,没有 python2 中的 Long。
- bool (布尔), 如 True。
- float (浮点数), 如 1.23、3E-2
- complex (复数), 如 1 + 2j、 1.1 + 2.2j
-
字符串
- 可以使用单引号或者双引号
- 使用三引号可以定义一个多行字符串
- 转义符
\
- 输出字符串时在前面添加
r
可以让反斜杠不发生转义 - 字符串可以使用
+
拼接,*
重复 - 字符串有两种索引方式,从左到右边以0开始,反之以-1开始
- python中的字符串不能改变
- 字符串的截取
字符串变量[开始下标:截至下标:步长]
-
空行
- 函数之间或类的方法之间用空行分隔,表示一段新的代码的开始。类和函数入口之间也用一行空行分隔,以突出函数入口的开始。
- 空行与代码缩进不同,空行并不是Python语法的一部分。书写时不插入空行,Python解释器运行也不会出错。但是空行的作用在于分隔两段不同功能或含义的代码,便于日后代码的维护或重构。
- 记住:空行也是程序代码的一部分。
-
python可以在同一行写多条语句,语句之间使用分号分隔
-
print()
函数输出时默认是换行的,实现不换行print( ···, end = '' )
-
import与from···import
- 使用上述两种方式来导入响应的模块
- 将整个模块导入
import XXX
- 从某个模块中导入某个函数
from XXX import XXX
,导入多个函数以逗号分隔,全部导入使用*
基本数据类型
-
python中变量不需要声明,但是在使用前必须赋值,变量被赋值后才会被创建
-
python允许多变量赋值
a = b = c = 1
或者a, b, c = 1, 2, 3
-
标准数据类型
- Number(数字)
- String(字符串)
- List(列表)
- Tuple(元组)
- Set(集合)
- Dictionary(字典)
- 不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);
- 可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。
-
Number数字
- Python3 支持 int、float、bool、complex(复数)
- 在Python 3里,只有一种整数类型 int,表示为长整型,没有 python2 中的 Long。
- 内置的 type() 函数可以用来查询变量所指的对象类型,此外还可以使用isinstance 来判断
isinstance(···, XXX)
- type不会认为子类是一种父类类型
- isinstance会认为子类是一种父类类型
- 注意:在 Python2 中是没有布尔型的,它用数字 0 表示 False,用 1 表示 True。到 Python3 中,把 True 和 False 定义成关键字了,但它们的值还是 1 和 0,它们可以和数字相加。
- 运算
- 基本运算
- // 舍余求整
- % 求余
- ** 幂运算
- Python还支持复数,复数由实数部分和虚数部分构成,可以用a + bj,或者complex(a,b)表示, 复数的实部a和虚部b都是浮点型
-
String字符串
- Python中的字符串用单引号 ' 或双引号 " 括起来,同时使用反斜杠\
转义特殊字符。
- 字符串的截取规则字符串变量[开始下标:结束下标]
- 索引值以 0 为开始值,-1 为从末尾的开始位置。
- 可以使用+拼接字符串,使用*重复字符串
- 在字符串前添加一个r将会忽略字符串中的转义字符,并将其直接输出
- 可以使用三引号定义一个字段 -
List列表
- 列表是写在方括号 [] 之间、用逗号分隔开的元素列表。
- 和字符串一样,列表同样可以被索引和截取,列表被截取后返回一个包含所需元素的新列表。
列表变量[头下标:尾下标]
,索引值以 0 为开始值,-1 为从末尾的开始位置,Python 列表截取可以接收第三个参数,参数作用是截取的步长,如果第三个参数为负数表示逆向读取 - +拼接列表,*重复操作列表
-
Tuple元组
-
元组(tuple)与列表类似,不同之处在于元组的元素不能修改。元组写在小括号 () 里,元素之间用逗号隔开。
-
虽然tuple的元素不可改变,但它可以包含可变的对象,比如list列表
-
构造包含 0 个或 1 个元素的元组比较特殊,所以有一些额外的语法规则
tup1 = () # 空元组 tup2 = (20,) # 一个元素,需要在元素后添加逗号
-
元组的操作类似于列表
-
-
set集合
-
集合(set)是由一个或数个形态各异的大小整体组成的,构成集合的事物或对象称作元素或是成员
-
基本功能是进行成员关系测试和删除重复元素。
-
可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。
-
实例
student = {'Tom', 'Jim', 'Mary', 'Tom', 'Jack', 'Rose'} print(student) # 输出集合,重复的元素被自动去掉 # 成员测试 if 'Rose' in student : print('Rose 在集合中') else : print('Rose 不在集合中') # set可以进行集合运算 a = set('abracadabra') b = set('alacazam') print(a) print(a - b) # a 和 b 的差集 print(a | b) # a 和 b 的并集 print(a & b) # a 和 b 的交集 print(a ^ b) # a 和 b 中不同时存在的元素
-
-
dictionary字典
-
列表是有序的对象集合,字典是无序的对象集合。两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取。
-
字典是一种映射类型,字典用 { } 标识,它是一个无序的 键(key) : 值(value) 的集合。
-
键(key)必须使用不可变类型。
-
在同一个字典中,键(key)必须是唯一的。
-
实例
dict = {} dict['one'] = "1 - 菜鸟教程" dict[2] = "2 - 菜鸟工具" tinydict = {'name': 'runoob','code':1, 'site': 'www.runoob.com'} print (dict['one']) # 输出键为 'one' 的值 print (dict[2]) # 输出键为 2 的值 print (tinydict) # 输出完整的字典 print (tinydict.keys()) # 输出所有键 print (tinydict.values()) # 输出所有值
-
构造函数 dict() 可以直接从键值对序列中构建字典如下
>>> dict([('Runoob', 1), ('Google', 2), ('Taobao', 3)]) {'Runoob': 1, 'Google': 2, 'Taobao': 3} >>> {x: x**2 for x in (2, 4, 6)} {2: 4, 4: 16, 6: 36} >>> dict(Runoob=1, Google=2, Taobao=3) {'Runoob': 1, 'Google': 2, 'Taobao': 3} >>>
-
-
数据类型转换
-
有时候,我们需要对数据内置的类型进行转换,数据类型的转换,你只需要将数据类型作为函数名即可
int(x, [base])
将x为整型,base为进制数默认为十进制,若指定进制数需要将数字以字符串的形式传入float(x)
将x转换为浮点数complex(real, [imag])
创建一个复数str(x)
将x转换为字符串repr(x)
将对象 x 转换为表达式字符串eval(x)
函数用来执行一个字符串表达式,并返回表达式的值tuple(x)
函数将可迭代系列(如列表)转换为元组list(x)
方法用于将元组或字符串转换为列表set(x)
函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集、差集、并集等dict(x)
函数用于创建一个字典
-
注释
- 单行注释使用
#
- 多行注释使用三引号(或者三个双引号都可以)
'''···'''
或者"""···"""
运算符
-
算术运算符
+ 加 - 两个对象相加 - 减 - 得到负数或是一个数减去另一个数 * 乘 - 两个数相乘或是返回一个被重复若干次的字符串 / 除 - x 除以 y % 取模 - 返回除法的余数 ** 幂 - 返回x的y次幂 // 取整除 - 向下取接近商的整数 -
比较运算符
== 等于 - 比较对象是否相等 != 不等于 - 比较两个对象是否不相等 > 大于 - 返回x是否大于y < 小于 - 返回x是否小于y。所有比较运算符返回1表示真,返回0表示假。这分别与特殊的变量True和False等价。注意,这些变量名的大写。 >= 大于等于 - 返回x是否大于等于y。 <= 小于等于 - 返回x是否小于等于y。 -
赋值运算符
= 简单的赋值运算符 += 加法赋值运算符 -= 减法赋值运算符 *= 乘法赋值运算符 /= 除法赋值运算符 %= 取模赋值运算符 **= 幂赋值运算符 //= 取整除赋值运算符 -
位运算符
& 按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0 | 按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。 ^ 按位异或运算符:当两对应的二进位相异时,结果为1 ~ 按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1。~x 类似于 -x-1 << 左移动运算符:运算数的各二进位全部左移若干位,由"<<"右边的数指定移动的位数,高位丢弃,低位补0。 >> 右移动运算符:把">>"左边的运算数的各二进位全部右移若干位,">>"右边的数指定移动的位数 -
逻辑运算符
and x and y 布尔"与" - 如果 x 为 False,x and y 返回 False,否则它返回 y 的计算值。 or x or y 布尔"或" - 如果 x 是 True,它返回 x 的值,否则它返回 y 的计算值。 not not x 布尔"非" - 如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。 -
成员运算符
in 如果在指定的序列中找到值返回 True,否则返回 False。 x 在 y 序列中 , 如果 x 在 y 序列中返回 True。 not in 如果在指定的序列中没有找到值返回 True,否则返回 False。 x 不在 y 序列中 , 如果 x 不在 y 序列中返回 True。 -
身份运算符
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()
函数用于获取对象内存地址。
- 注:
-
优先级
** 指数 (最高优先级) ~ + - 按位翻转, 一元加号和减号 (最后两个的方法名为 +@ 和 -@) * / % // 乘,除,求余数和取整除 + - 加法减法 >> << 右移,左移运算符 & 位 'AND' ^ | 位运算符 <= < > >= 比较运算符 == != 等于运算符 = %= /= //= -= += *= **= 赋值运算符 is is not 身份运算符 in not in 成员运算符 not and or 逻辑运算符
Number数字
-
Python 数字数据类型用于存储数值。
-
数据类型是不允许改变的,这就意味着如果改变数字数据类型的值,将重新分配内存空间。
-
在整数除法中,除法 / 总是返回一个浮点数,如果只想得到整数的结果,丢弃可能的分数部分,可以使用运算符 //
-
注意:****// 得到的并不一定是整数类型的数,它与分母分子的数据类型有关系
-
不同类型的数混合运算时会将整数转换为浮点数
-
在交互模式中,最后被输出的表达式结果被赋值给变量 _
-
数学函数
函数 返回值 ( 描述 ) 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 已废弃 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(···) 返回给定参数的最大值,参数可以为序列。 min(···) 返回给定参数的最小值,参数可以为序列。 modf(x) 返回x的整数部分与小数部分,两部分的数值符号与x相同,整数部分以浮点型表示。 pow(x,y) x**y 运算后的值。 round(x,[n]) 返回浮点数 x 的四舍五入值,如给出 n 值,则代表舍入到小数点后的位数。其实准确的说是保留值将保留到离上一位更近的一端。 sqrt(x) 返回数字x的平方根。 -
随机数函数
注意:下列方法是不能直接访问的,需要导入 random 模块,然后通过 random 静态对象调用该方法
- choice(seq) 方法返回一个列表,元组或字符串的随机项
- randrange([start,] stop [,step]) 方法返回指定递增基数集合中的一个随机数,基数默认值为1
- start -- 指定范围内的开始值,包含在范围内。
- stop -- 指定范围内的结束值,不包含在范围内。
- step -- 指定递增基数。
- random() 方法返回随机生成的一个实数,它在[0,1)范围内。
- seed() 方法改变随机数生成器的种子,可以在调用其他随机模块函数之前调用此函数
- x -- 改变随机数生成器的种子seed。如果你不了解其原理,你不必特别去设定seed,Python会帮你选择seed
- 我们调用 random.random() 生成随机数时,每一次生成的数都是随机的。但是,当我们预先使用 random.seed(x) 设定好种子之后,其中的 x 可以是任意数字,如10,这个时候,先调用它的情况下,使用 random() 生成的随机数将会是同一个
- shuffle() 方法将序列的所有元素随机排序
- uniform(x,y) 方法将随机生成下一个实数,它在 [x,y] 范围内。
字符串
-
可以使用单引号或者双引号来创建字符串
-
截取字符串
字符串变量[起始位置:结束位置]
-
转义字符
转义字符 描述 \(在行尾时) 续行符 \\ 反斜杠符号 \' 单引号 \" 双引号 \a 响铃 \b 退格(Backspace) \000 空 \n 换行 \v 纵向制表符 \t 横向制表符 \r 回车 \f 换页 \oyy 八进制数,yy 代表的字符,例如:\o12 代表换行,其中 o 是字母,不是数字 0。 \xyy 十六进制数,yy代表的字符,例如:\x0a代表换行 \other 其它的字符以普通格式输出 -
字符串运算符
下表实例变量a值为字符串 "Hello",b变量值为 "Python":
操作符 描述 实例 + 字符串连接 a + b 输出结果: HelloPython * 重复输出字符串 a*2 输出结果:HelloHello [] 通过索引获取字符串中字符 a[1] 输出结果 e [ : ] 截取字符串中的一部分,遵循左闭右开原则,str[0:2] 是不包含第 3 个字符的。 a[1:4] 输出结果 ell in 成员运算符 - 如果字符串中包含给定的字符返回 True 'H' in a 输出结果 True not in 成员运算符 - 如果字符串中不包含给定的字符返回 True 'M' not in a 输出结果 True r/R 原始字符串 - 原始字符串:所有的字符串都是直接按照字面的意思来使用,没有转义特殊或不能打印的字符。 原始字符串除在字符串的第一个引号前加上字母 r(可以大小写)以外,与普通字符串有着几乎完全相同的语法。 print( r'\n' ) print( R'\n' )
-
字符串格式化
-
Python 支持格式化字符串的输出 。尽管这样可能会用到非常复杂的表达式,但最基本的用法是将一个值插入到一个有字符串格式符 %s 的字符串中
-
例如
print ("我叫 %s 今年 %d 岁!" % ('小明', 10))
-
字符串格式化符号
符 号 描述 %c 格式化字符及其ASCII码 %s 格式化字符串 %d 格式化整数 %u 格式化无符号整型 %o 格式化无符号八进制数 %x 格式化无符号十六进制数 %X 格式化无符号十六进制数(大写) %f 格式化浮点数字,可指定小数点后的精度 %e 用科学计数法格式化浮点数 %E 作用同%e,用科学计数法格式化浮点数 %g %f和%e的简写 %G %f 和 %E 的简写 %p 用十六进制数格式化变量的地址 -
格式化操作符辅助指令
符号 功能 * 定义宽度或者小数点精度 - 用做左对齐 + 在正数前面显示加号( + ) 在正数前面显示空格 # 在八进制数前面显示零('0'),在十六进制前面显示'0x'或者'0X'(取决于用的是'x'还是'X') 0 显示的数字前面填充'0'而不是默认的空格 % '%%'输出一个单一的'%' (var) 映射变量(字典参数) m.n. m 是显示的最小总宽度,n 是小数点后的位数(如果可用的话) - Python2.6 开始,新增了一种格式化字符串的函数 str.format(),它增强了字符串格式化的功能。
-
-
三引号
- python三引号允许一个字符串跨多行,字符串中可以包含换行符、制表符以及其他特殊字符
- 三引号让程序员从引号和特殊字符串的泥潭里面解脱出来,自始至终保持一小块字符串的格式是所谓的WYSIWYG(所见即所得)格式的
-
在Python3中,所有的字符串都是Unicode字符串。
-
字符串常用内建函数
序号 方法及描述 1 capitalize() 将字符串的第一个字符转换为大写 2 center(width, fillchar) 返回一个指定的宽度 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)) 检查字符串是否以 obj 结束,如果beg 或者 end 指定则检查指定的范围内是否以 obj 结束,如果是,返回 True,否则返回 False. 7 expandtabs(tabsize=8) 把字符串 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 isalnum() 如果字符串至少有一个字符并且所有字符都是字母或数字则返 回 True,否则返回 False 11 isalpha() 如果字符串至少有一个字符并且所有字符都是字母则返回 True, 否则返回 False 12 isdigit() 如果字符串只包含数字则返回 True 否则返回 False.. 13 islower() 如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写,则返回 True,否则返回 False 14 isnumeric() 如果字符串中只包含数字字符,则返回 True,否则返回 False 15 isspace() 如果字符串中只包含空白,则返回 True,否则返回 False. 16 istitle() 如果字符串是标题化的(见 title())则返回 True,否则返回 False 17 isupper() 如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是大写,则返回 True,否则返回 False 18 join(seq) 以指定字符串作为分隔符,将 seq 中所有的元素(的字符串表示)合并为一个新的字符串 19 len(string) 返回字符串长度 20 [ljust(width, fillchar]) 返回一个原字符串左对齐,并使用 fillchar 填充至长度 width 的新字符串,fillchar 默认为空格。 21 lower() 转换字符串中所有大写字符为小写. 22 lstrip() 截掉字符串左边的空格或指定字符。 23 maketrans() 创建字符映射的转换表,对于接受两个参数的最简单的调用方式,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标。 24 max(str) 返回字符串 str 中最大的字母。 25 min(str) 返回字符串 str 中最小的字母。 26 [replace(old, new , max]) 把 将字符串中的 str1 替换成 str2,如果 max 指定,则替换不超过 max 次。 27 rfind(str, beg=0,end=len(string)) 类似于 find()函数,不过是从右边开始查找. 28 rindex( str, beg=0, end=len(string)) 类似于 index(),不过是从右边开始. 29 [rjust(width,, fillchar]) 返回一个原字符串右对齐,并使用fillchar(默认空格)填充至长度 width 的新字符串 30 rstrip() 删除字符串字符串末尾的空格. 31 split(str="", num=string.count(str)) num=string.count(str)) 以 str 为分隔符截取字符串,如果 num 有指定值,则仅截取 num+1 个子字符串 32 [splitlines(keepends]) 按照行('\r', '\r\n', \n')分隔,返回一个包含各行作为元素的列表,如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符。 33 startswith(substr, beg=0,end=len(string)) 检查字符串是否是以指定子字符串 substr 开头,是则返回 True,否则返回 False。如果beg 和 end 指定值,则在指定范围内检查。 34 [strip(chars]) 在字符串上执行 lstrip()和 rstrip() 35 swapcase() 将字符串中大写转换为小写,小写转换为大写 36 title() 返回"标题化"的字符串,就是说所有单词都是以大写开始,其余字母均为小写(见 istitle()) 37 translate(table, deletechars="") 根据 str 给出的表(包含 256 个字符)转换 string 的字符, 要过滤掉的字符放到 deletechars 参数中 38 upper() 转换字符串中的小写字母为大写 39 zfill (width) 返回长度为 width 的字符串,原字符串右对齐,前面填充0 40 isdecimal() 检查字符串是否只包含十进制字符,如果是返回 true,否则返回 false
列表
-
序列是Python中最基本的数据结构。序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推
-
Python有6个序列的内置类型,但最常见的是列表和元组。
-
序列都可以进行的操作包括索引,切片,加,乘,检查成员。
-
列表是最常用的Python数据类型,它可以作为一个方括号内的逗号分隔值出现。
-
列表的数据项不需要具有相同的类型
-
截取列表
列表变量/列表[起始位置:结束位置]
-
更新列表
- 简单的更新
列表变量/列表[指定索引] = XXX
- 删除列表元素
del 列表变量/列表[指定索引]
- 简单的更新
-
列表脚本操作符
- 列表对 + 和 * 的操作符与字符串相似。+ 号用于组合列表,* 号用于重复列表。
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) 将元组转换为列表 序号 方法 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() 复制列表
元组
-
元组使用小括号,不可修改
-
创建元组的时候也可以省略小括号
tup = 1,2,3
,内部仅有单个数据时,创建必须在后面添加上逗号tup = (XX,)
-
元组与字符串类似,下标索引从0开始,可以进行截取,组合等
-
元组不可修改,但是多个元组之间可以使用+拼接
-
元组运算符
Python 表达式 结果 描述 len((1, 2, 3)) 3 计算元素个数 (1, 2, 3) + (4, 5, 6) (1, 2, 3, 4, 5, 6) 连接 ('Hi!',) * 4 ('Hi!', 'Hi!', 'Hi!', 'Hi!') 复制 3 in (1, 2, 3) True 元素是否存在 for x in (1, 2, 3): print (x,) 1 2 3 迭代 -
元组内置函数
序号 方法及描述 实例 1 len(tuple) 计算元组元素个数。 >>> tuple1 = ('Google', 'Runoob', 'Taobao') >>> len(tuple1) 3 >>>
2 max(tuple) 返回元组中元素最大值。 >>> tuple2 = ('5', '4', '8') >>> max(tuple2) '8' >>>
3 min(tuple) 返回元组中元素最小值。 >>> tuple2 = ('5', '4', '8') >>> min(tuple2) '4' >>>
4 tuple(iterable) 将可迭代系列转换为元组。 >>> list1= ['Google', 'Taobao', 'Runoob', 'Baidu'] >>> tuple1=tuple(list1) >>> tuple1 ('Google', 'Taobao', 'Runoob', 'Baidu')
字典
-
字典是另一种可变容器模型,且可存储任意类型对象。
-
字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,键必须是唯一的,但值则不必
dict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'}
-
访问字典中的数据
dict['Name']
,修改与添加类似 -
删除键
del dict['Name']
,清空字典dict.clear()
-
不允许同一个键出现两次。创建时如果同一个键被赋值两次,后一个值会被记住
-
键必须不可变,所以可以用数字,字符串或元组充当
-
字典内置函数
序号 函数及描述 实例 1 len(dict) 计算字典元素个数,即键的总数。 >>> dict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'} >>> len(dict) 3
2 str(dict) 输出字典,以可打印的字符串表示。 >>> dict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'} >>> str(dict) "{'Name': 'Runoob', 'Class': 'First', 'Age': 7}"
3 type(variable) 返回输入的变量类型,如果变量是字典就返回字典类型。 >>> dict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First'} >>> type(dict)
序号 函数及描述 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() 随机返回并删除字典中的最后一对键和值。
集合
-
集合(set)是一个无序的不重复元素序列。
-
可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。
i = {'name', 'age', 'sex'}
j = set('abc')
-
集合之间的运算
>>> a = set('abracadabra') >>> b = set('alacazam') >>> a {'a', 'r', 'b', 'c', 'd'} >>> a - b # 集合a中包含而集合b中不包含的元素 {'r', 'd', 'b'} >>> a | b # 集合a或b中包含的所有元素 {'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'} >>> a & b # 集合a和b中都包含了的元素 {'a', 'c'} >>> a ^ b # 不同时包含于a和b的元素 {'r', 'd', 'b', 'm', 'z', 'l'}
-
集合的基本操作
s.add(x)
将元素 x 添加到集合 s 中,如果元素已存在,则不进行任何操作s.update( x )
也可以添加元素,且参数可以是列表,元组,字典等,x 可以有多个,用逗号分开s.remove( x )
将元素 x 从集合 s 中移除,如果元素不存在,则会发生错误s.discard( x )
方法也是移除集合中的元素,且如果元素不存在,不会发生错误s.pop()
随机删除集合中的一个元素,set 集合的 pop 方法会对集合进行无序的排列,然后将这个无序排列集合的左面第一个元素进行删除。len(s)
计算集合中元素的个数s.clear()
清空集合
完整方法
方法 描述 add() 为集合添加元素 clear() 移除集合中的所有元素 copy() 拷贝一个集合 difference() 返回多个集合的差集 difference_update() 移除集合中的元素,该元素在指定的集合也存在。 discard() 删除集合中指定的元素 intersection() 返回集合的交集 intersection_update() 返回集合的交集。 isdisjoint() 判断两个集合是否包含相同的元素,如果没有返回 True,否则返回 False。 issubset() 判断指定集合是否为该方法参数集合的子集。 issuperset() 判断该方法的参数集合是否为指定集合的子集 pop() 随机移除元素 remove() 移除指定元素 symmetric_difference() 返回两个集合中不重复的元素集合。 symmetric_difference_update() 移除当前集合中在另外一个指定集合相同的元素,并将另外一个指定集合中不同的元素插入到当前集合中。 union() 返回两个集合的并集 update() 给集合添加元素
python编程
初识
- end关键字可以用于将结果输出到同一行,或者在输出的末尾添加不同的字符
a, b = 0, 1
while b < 10:
print(b, end=',')
a, b = b, a+b
// 输出1,1,2,3,5,8,
条件控制语句
-
示例
if condition_1: statement_block_1 elif condition_2: statement_block_2 else: statement_block_3
- 每个条件后面要使用冒号 :,表示接下来是满足条件后要执行的语句块。
- 使用缩进来划分语句块,相同缩进数的语句在一起组成一个语句块。
- 在Python中没有switch – case语句。
-
常用操作运算符
操作符 描述 <
小于 <=
小于或等于 >
大于 >=
大于或等于 ==
等于,比较两个值是否相等 !=
不等于
循环语句
-
while循环
-
while语句的一般形式
while 判断条件(condition): 执行语句(statements)……
-
在 while … else 在条件语句为 false 时执行 else 的语句块
while
: else: -
类似if语句的语法,如果你的while循环体中只有一条语句,你可以将该语句与while写在同一行中
flag = 1 while (flag): print ('欢迎访问菜鸟教程!') print ("Good bye!")
-
-
for循环
-
Python for循环可以遍历任何序列的项目,如一个列表或者一个字符串
for
in : else: -
以下 for 实例中使用了 break 语句,break 语句用于跳出当前循环体
sites = ["Baidu", "Google","Runoob","Taobao"] for site in sites: if site == "Runoob": print("菜鸟教程!") break print("循环数据 " + site) else: print("没有循环数据!") print("完成循环!")
-
-
range函数
-
如果你需要遍历数字序列,可以使用内置range()函数
for i in range(5): print(i) #输出结果 0 1 2 3 4
-
你也可以使用range指定区间的值
for i in range(5,9): print(i) #输出结果 5 6 7 8
-
也可以使range以指定数字开始并指定不同的增量(甚至可以是负数,有时这也叫做'步长
for i in range(0, 10, 3) : print(i) #输出结果 0 3 6 9
-
-
break 语句可以跳出 for 和 while 的循环体。如果你从 for 或 while 循环中终止,任何对应的循环 else 块将不执行。
-
continue 语句被用来告诉 Python 跳过当前循环块中的剩余语句,然后继续进行下一轮循环
-
循环语句可以有 else 子句,它在穷尽列表(以for循环)或条件变为 false (以while循环)导致循环终止时被执行,但循环被 break 终止时不执行
-
pass是空语句,是为了保持程序结构的完整性
迭代器与生成器
-
迭代器是一个可以记住遍历的位置的对象
-
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退
-
迭代器有两个基本的方法:iter() 和 next()。
list1 = ['tom', 'ailce', 'erick'] #创建迭代器对象 it = iter(list1) #输出迭代器的下一个元素 print(next(it)) #tom print(next(it)) #alice
-
迭代器对象可以使用常规for语句进行遍历
list1 = ['tom', 'ailce', 'erick'] it = iter(list1) for i in it: print(i)
-
也可以使用next函数
list1 = [1,2,3,4,5] it = iter(list1) mark = True while mark: try: print(next(it)) except StopIteration: mark = False ### 输出: 1 2 3 4 5
-
创建一个迭代器
- 把一个类作为一个迭代器使用需要在类中实现两个方法 iter() 与 next() 。
- iter() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 next() 方法并通过 StopIteration 异常标识迭代的完成
- next() 方法(Python 2 里是 next())会返回下一个迭代器对象。
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 #创建一个返回数字的迭代器,初始值为 1,逐步递增 1
-
StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,在 next() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代。
-
生成器
-
在 Python 中,使用了 yield 的函数被称为生成器(generator)
-
跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
-
在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。
-
调用一个生成器函数,返回的是一个迭代器对象。
-
示例
import sys def fibonacci(n): # 生成器函数 - 斐波那契 a, b, counter = 0, 1, 0 while True: if (counter > n): return yield a a, b = b, a + b counter += 1 f = fibonacci(10) # f 是一个迭代器,由生成器返回生成 while True: try: print (next(f), end=" ") except StopIteration: sys.exit() #以下实例使用 yield 实现斐波那契数列
-
函数
-
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段
-
你可以定义一个由自己想要功能的函数,以下是简单的规则:
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。
- 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
def add(x,y): return x+y
-
可更改(mutable)与不可更改(immutable)对象
在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。
- 不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。
- 可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。
python 函数的参数传递:
- 不可变类型:类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。
- 可变类型:类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响
python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象
def change(x): x += 1 print(x) a = 1 change(a) #2 print(a) #1
def change(listx): listx.append('mark') print(listx) list1 = ['a', 'b', 'c'] change(list1) #['a', 'b', 'c', 'mark'] print(list1) #['a', 'b', 'c', 'mark']
-
参数
-
必须参数
- 必需参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样
def change(listx): listx.append('mark') print(listx) change() #TypeError: change() missing 1 required positional argument: 'listx'
-
关键字参数
- 关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
- 使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值
def fun1(name, age): print('姓名:' + name, '年龄:' + age) fun1(age='12', name='小明') #姓名:小明 年龄:12
-
默认参数
- 调用函数时,如果没有传递参数,则会使用默认参数。以下实例中如果没有传入 age 参数,则使用默认值
def fun1(name, age='18'): print('姓名:' + name, '年龄:' + age) fun1('小明') #姓名:小明 年龄:18
-
不定长参数
- 你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述 2 种参数不同,声明时不会命名。基本语法如下
def functionname([formal_args,] *var_args_tuple ): "函数_文档字符串" function_suite return [expression]
- 加了星号 ***** 的参数会以元组(tuple)的形式导入,存放所有未命名的变量参数。
# 可写函数说明 def printinfo( arg1, *vartuple ): "打印任何传入的参数" print ("输出: ") print (arg1) print (vartuple) # 调用printinfo 函数 printinfo( 70, 60, 50 )
def fun1(x,*vartuple): print(x) print(vartuple) fun1(1,2,3,4,5) #1 #(2, 3, 4, 5)
- 如果在函数调用时没有指定参数,它就是一个空元组。我们也可以不向函数传递未命名的变量
- 还有一种就是参数带两个星号 **基本语法如下
- 加了两个星号 ** 的参数会以字典的形式导入
def functionname([formal_args,] **var_args_dict ): "函数_文档字符串" function_suite return [expression]
def fun1(x,**vardict): print(x) print(vardict) fun1(1,name='tom',age=12) #1 #{'name': 'tom', 'age': 12}
- 声明函数时,参数中星号 ***** 可以单独出现,如果单独出现星号 ***** 后的参数必须用关键字传入
def fun1(x,y,*,z): print(x,y) print(z) fun1(1,2,3) #TypeError: fun1() takes 2 positional arguments but 3 were given
def fun1(x,y,*,z): print(x,y) print(z) fun1(1,2,z=3) #1 2 #3
-
匿名函数
-
python 使用 lambda 来创建匿名函数
-
所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。
- lambda 只是一个表达式,函数体比 def 简单很多。
- lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
- lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
- 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率
-
lambda 函数的语法只包含一个语句,如下:
lambda [arg1 [,arg2,.....argn]]:expression
fun1 = lambda x, y: x+y print(fun1(1,2)) #3
-
-
return语句
- return [表达式] 语句用于退出函数,选择性地向调用方返回一个表达式。不带参数值的return语句返回None。
python数据结构(补充列表)
-
列表
方法 描述 list.append(x) 把一个元素添加到列表的结尾,相当于 a[len(a):] = [x]。 list.extend(L) 通过添加指定列表的所有元素来扩充列表,相当于 a[len(a):] = L。 list.insert(i, x) 在指定位置插入一个元素。第一个参数是准备插入到其前面的那个元素的索引,例如 a.insert(0, x) 会插入到整个列表之前,而 a.insert(len(a), x) 相当于 a.append(x) 。 list.remove(x) 删除列表中值为 x 的第一个元素。如果没有这样的元素,就会返回一个错误。 list.pop([i]) 从列表的指定位置移除元素,并将其返回。如果没有指定索引,a.pop()返回最后一个元素。元素随即从列表中被移除。(方法中 i 两边的方括号表示这个参数是可选的,而不是要求你输入一对方括号,你会经常在 Python 库参考手册中遇到这样的标记。) list.clear() 移除列表中的所有项,等于del a[:]。 list.index(x) 返回列表中第一个值为 x 的元素的索引。如果没有匹配的元素就会返回一个错误。 list.count(x) 返回 x 在列表中出现的次数。 list.sort() 对列表中的元素进行排序。 list.reverse() 倒排列表中的元素。 list.copy() 返回列表的浅复制,等于a[:]。 -
将列表当作堆栈使用
- 列表方法使得列表可以很方便的作为一个堆栈来使用,堆栈作为特定的数据结构,最先进入的元素最后一个被释放(后进先出)。用 append() 方法可以把一个元素添加到堆栈顶。用不指定索引的 pop() 方法可以把一个元素从堆栈顶释放出来
stack = ['a', 'b', 'c'] print(stack.pop()) print(stack.pop()) print(stack.pop()) #c #b #a
- 也可以把列表当做队列用,只是在队列里第一加入的元素,第一个取出来;但是拿列表用作这样的目的效率不高。在列表的最后添加或者弹出元素速度快,然而在列表里插入或者从头部弹出速度却不快(因为所有其他的元素都得一个一个地移动)
from collections import deque queue = deque(['a', 'b', 'c']) print(queue.popleft()) #a #b #c
-
列表推导式
- 列表推导式提供了从序列创建列表的简单途径。通常应用程序将一些操作应用于某个序列的每个元素,用其获得的结果作为生成新列表的元素,或者根据确定的判定条件创建子序列。
- 每个列表推导式都在 for 之后跟一个表达式,然后有零到多个 for 或 if 子句。返回结果是一个根据表达从其后的 for 和 if 上下文环境中生成出来的列表。如果希望表达式推导出一个元组,就必须使用括号。
list1 = [1,2,3] list2 = [x**2 for x in list1] print(list2) #[1, 4, 9]
list1 = [1,2,3] list2 = [[x, x**2] for x in list1] print(list2) #[[1, 1], [2, 4], [3, 9]]
list1 = [1,2,3,4,5] list2 = [x for x in list1 if x%2 == 0] print(list2) #[2,4]
list1 = [1,2] list2 = [3,4] list3 = [x*y for x in list1 for y in list2] print(list3) #[3, 4, 6, 8]
-
遍历序列技巧
- 在字典中遍历时,关键字和对应的值可以使用 items() 方法同时解读出来
dict1 = {'name': '小明', 'age': 12} for key,value in dict1.items(): print(key,value) #name 小明 #age 12
- 在序列中遍历时,索引位置和对应值可以使用 enumerate() 函数同时得到:
list1 = ['a', 'b', 'c'] for index,value in enumerate(list1): print(index, value) #0 a #1 b #2 c
- 同时遍历两个或更多的序列,可以使用 zip() 组合:
person1 = ['name', 'age', 'id'] info1 = ['小明', 12, '122qwexxxs009'] for p,i in zip(person1,info1): print('{0}: {1}'.format(p,i)) #name: 小明 #age: 12 #id: 122qwexxxs009
- 要反向遍历一个序列,首先指定这个序列,然后调用 reversed() 函数
person1 = ['name', 'age', 'id'] for i in reversed(person1): print(i) #id #age #name
-
模块
-
为此 Python 提供了一个办法,把这些定义存放在文件中,为一些脚本或者交互式的解释器实例使用,这个文件被称为模块。
-
模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py。模块可以被别的程序引入,以使用该模块中的函数等功能。这也是使用 python 标准库的方法。
-
想使用 Python 源文件,只需在另一个源文件里执行 import 语句
import module1[, module2[,... moduleN]
- 当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入
- 搜索路径是一个解释器会先进行搜索的所有目录的列表
-
一个模块只会被导入一次,不管你执行了多少次import
-
模块的搜索路径是在Python编译或安装的时候确定的,安装新的库应该也会修改。搜索路径被存储在sys模块中的path变量
-
Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中
from modname import name1[, name2[, ... nameN]]
-
将一个模块中所有的内容导入到当前的模块
from modname import *
-
深入模块
-
模块除了方法定义,还可以包括可执行的代码。这些代码一般用来初始化这个模块。这些代码只有在第一次被导入时才会被执行。
-
每个模块有各自独立的符号表,在模块内部为所有的函数当作全局符号表来使用。
-
当你确实知道你在做什么的话,你也可以通过 modname.itemname 这样的表示法来访问模块内的函数
-
模块是可以导入其他模块的
-
__name__
属性- 一个模块被另一个程序第一次引入时,其主程序将运行。如果我们想在模块被引入时,模块中的某一程序块不执行,我们可以用__name__属性来使该程序块仅在该模块自身运行时执行
# Filename: module1.py if __name__ == '__main__': print('1') else: print('2') #运行后输出1
# Filename: test.py import module1 #运行后输出2
-
说明: 每个模块都有一个__name__属性,当其值是'main'时,表明该模块自身在运行,否则是被引入。
说明:name 与 main 底下是双下划线, _ _ 是这样去掉中间的那个空格。
-
内置的函数 dir() 可以找到模块内定义的所有名称。以一个字符串列表的形式返回
-
标准模块
- Python 本身带着一些标准的模块库,在 Python 库参考文档中将会介绍到
- 有些模块直接被构建在解析器里,这些虽然不是一些语言内置的功能,但是他却能很高效的使用,甚至是系统级调用也没问题。
- 这些组件会根据不同的操作系统进行不同形式的配置,比如 winreg 这个模块就只会提供给 Windows 系统
- 应该注意到这有一个特别的模块 sys ,它内置在每一个 Python 解析器中
-
包
-
包是一种管理 Python 模块命名空间的形式,采用"点模块名称"
-
比如一个模块的名称是 A.B, 那么他表示一个包 A中的子模块 B
-
就好像使用模块的时候,你不用担心不同模块之间的全局变量相互影响一样,采用点模块名称这种形式也不用担心不同库之间的模块重名的情况
-
不妨假设你想设计一套统一处理声音文件和数据的模块(或者称之为一个"包")。
现存很多种不同的音频文件格式(基本上都是通过后缀名区分的,例如: .wav,:file:.aiff,:file:.au,),所以你需要有一组不断增加的模块,用来在不同的格式之间转换。
并且针对这些音频数据,还有很多不同的操作(比如混音,添加回声,增加均衡器功能,创建人造立体声效果),所以你还需要一组怎么也写不完的模块来处理这些操作。
这里给出了一种可能的包结构(在分层的文件系统中):
sound/ 顶层包 __init__.py 初始化 sound 包 formats/ 文件格式转换子包 __init__.py wavread.py wavwrite.py aiffread.py aiffwrite.py auread.py auwrite.py ... effects/ 声音效果子包 __init__.py echo.py surround.py reverse.py ... filters/ filters 子包 __init__.py equalizer.py vocoder.py karaoke.py ...
-
在导入一个包的时候,Python 会根据 sys.path 中的目录来寻找这个包中包含的子目录
-
目录只有包含一个叫做 init.py 的文件才会被认作是一个包,主要是为了避免一些滥俗的名字(比如叫做 string)不小心的影响搜索路径中的有效模块
-
最简单的情况,放一个空的 :file:init.py就可以了。当然这个文件中也可以包含一些初始化代码或者为(将在后面介绍的) __all__变量赋值。用户可以每次只导入一个包里面的特定模块,比如:
import sound.effects.echo
-
这将会导入子模块:sound.effects.echo。 他必须使用全名去访问
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
-
还有一种导入子模块的方法是:
from sound.effects import echo
-
这同样会导入子模块: echo,并且他不需要那些冗长的前缀,所以他可以这样使用:
echo.echofilter(input, output, delay=0.7, atten=4)
-
还有一种变化就是直接导入一个函数或者变量:
from sound.effects.echo import echofilter
-
同样的,这种方法会导入子模块: echo,并且可以直接使用他的 echofilter() 函数:
echofilter(input, output, delay=0.7, atten=4)
-
注意当使用 from package import item 这种形式的时候,对应的 item 既可以是包里面的子模块(子包),或者包里面定义的其他名称,比如函数,类或者变量
-
import 语法会首先把 item 当作一个包定义的名称,如果没找到,再试图按照一个模块去导入。如果还没找到,抛出一个 :exc:ImportError 异常。
-
反之,如果使用形如 import item.subitem.subsubitem 这种导入形式,除了最后一项,都必须是包,而最后一项则可以是模块或者是包,但是不可以是类,函数或者变量的名字。
-
从一个包中导入*
- 导入语句遵循如下规则:如果包定义文件 init.py 存在一个叫做 all 的列表变量,那么在使用 from package import * 的时候就把这个列表中的所有名字作为包内容导入。
- 别忘了在更新包之后保证
__all__
也更新 - 无论是隐式的还是显式的相对导入都是从当前模块开始的。主模块的名字永远是"main",一个Python应用程序的主模块,应当总是使用绝对路径引用。
- 包还提供一个额外的属性__path__。这是一个目录列表,里面每一个包含的目录都有为这个包服务的__init__.py,你得在其他__init__.py被执行前定义哦。可以修改这个变量,用来影响包含在包里面的模块和子包(并不常用)
-
该方面的细节还需要进一步理解
-
输入和输出
-
Python两种输出值的方式: 表达式语句和 print() 函数
-
第三种方式是使用文件对象的 write() 方法,标准输出文件可以用 sys.stdout 引用
-
如果你希望输出的形式更加多样,可以使用 str.format() 函数来格式化输出值
-
如果你希望将输出的值转成字符串,可以使用 repr() 或 str() 函数来实现。
- str(): 函数返回一个用户易读的表达形式。
- repr(): 产生一个解释器易读的表达形式。
-
示例
str1 = 'hello python' str(str1) #'hello python' repr(str1) #"'hello python'" str1 = 'Hello Python\n' repr(str1) #直接输出转义字符
-
str.format() 的基本使用
print('姓名:{0},年龄:{1}'.format('小明',12)) #输出 姓名:小明,年龄:12
- 括号及其里面的字符 (称作格式化字段) 将会被 format() 中的参数替换
- 在括号中的数字用于指向传入对象在 format() 中的位置
- 如果在 format() 中使用了关键字参数, 那么它们的值会指向使用该名字的参数
print('姓名:{name},年龄:{age}'.format(name='小明',age=12))
-
!a (使用 ascii()), !s (使用 str()) 和 !r (使用 repr()) 可以用于在格式化某个值之前对其进行转化
-
可选项 : 和格式标识符可以跟着字段名。 这就允许对值进行更好的格式化
print('{0:.3f}'.format(math.pi))
-
如果你有一个很长的格式化字符串, 而你不想将它们分开, 那么在格式化时通过变量名而非位置会是很好的事情。最简单的就是传入一个字典, 然后使用方括号 [] 来访问键值
>>> table = {'Google': 1, 'Runoob': 2, 'Taobao': 3} >>> print('Runoob: {0[Runoob]:d}; Google: {0[Google]:d}; Taobao: {0[Taobao]:d}'.format(table)) Runoob: 2; Google: 1; Taobao: 3
-
也可以通过在 table 变量前使用 ** 来实现相同的功能
>>> table = {'Google': 1, 'Runoob': 2, 'Taobao': 3} >>> print('Runoob: {Runoob:d}; Google: {Google:d}; Taobao: {Taobao:d}'.format(**table)) Runoob: 2; Google: 1; Taobao: 3
-
旧字符串格式化
- % 操作符也可以实现字符串格式化。 它将左边的参数作为类似 sprintf() 式的格式化字符串, 而将右边的代入, 然后返回格式化后的字符串
print('常量PI的值为%5.3f'%math.pi)
- 因为 str.format() 是比较新的函数, 大多数的 Python 代码仍然使用 % 操作符。但是因为这种旧式的格式化最终会从该语言中移除, 应该更多的使用 str.format()
-
读取键盘输入
- Python提供了 input() 内置函数从标准输入读入一行文本,默认的标准输入是键盘
- input 可以接收一个Python表达式作为输入,并将运算结果返回
x = input('请请输入内容:')
-
读取和写入文件
- open() 将会返回一个 file 对象
open(filename, mode)
- filename:包含了你要访问的文件名称的字符串值。
- mode:决定了打开文件的模式:只读,写入,追加等。所有可取值见如下的完全列表。这个参数是非强制的,默认文件访问模式为只读(r)。
模式 描述 r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。 r+ 打开一个文件用于读写。文件指针将会放在文件的开头。 rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 w 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 w+ 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 wb+ 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 ab 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 ab+ 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 模式 r :--------: :--: 读 + 写 创建 覆盖 指针在开始 + 指针在结尾 file1 = open('./write.txt', 'w') file1.write('Hello Python') file1.close()
- open() 将会返回一个 file 对象
-
文件对象的方法
-
f.read()
- 为了读取一个文件的内容,调用 f.read(size), 这将读取一定数目的数据, 然后作为字符串或字节对象返回。
- size 是一个可选的数字类型的参数。 当 size 被忽略了或者为负, 那么该文件的所有内容都将被读取并且返回
-
f.readline()
- f.readline() 会从文件中读取单独的一行。换行符为 '\n'。f.readline() 如果返回一个空字符串, 说明已经已经读取到最后一行
-
f.readlines()
- f.readlines() 将返回该文件中包含的所有行。
- 如果设置可选参数 sizehint, 则读取指定长度的字节, 并且将这些字节按行分割
-
迭代一个文件对象然后读取每行
file1 = open('./write.txt', 'r') for i in file1: print(i, end='') file1.close() #Hello Python #Hello Java #Hello Javascript
-
f.write()
- f.write(string) 将 string 写入到文件中, 然后返回写入的字符数
- 如果要写入一些不是字符串的东西, 那么将需要先进行转换
-
f.tell()
- f.tell() 返回文件对象当前所处的位置, 它是从文件开头开始算起的字节数。
-
f.seek()
- 如果要改变文件当前的位置, 可以使用 f.seek(offset, from_what) 函数。
- from_what 的值, 如果是 0 表示开头, 如果是 1 表示当前位置, 2 表示文件的结尾
- seek(x,0) : 从起始位置即文件首行首字符开始移动 x 个字符
- seek(x,1) : 表示从当前位置往后移动x个字符
- seek(-x,2):表示从文件的结尾往前移动x个字符
-
f.close()
- 在文本文件中 (那些打开文件的模式下没有 b 的), 只会相对于文件起始位置进行定位。
- 当你处理完一个文件后, 调用 f.close() 来关闭文件并释放系统的资源,如果尝试再调用该文件,则会抛出异常
- 当处理一个文件对象时, 使用 with 关键字是非常好的方式。在结束后, 它会帮你正确的关闭文件
with open('./write.txt', 'r') as file1: print(file1.read())
-
文件对象还有其他方法, 如 isatty() 和 trucate(), 但这些通常比较少用
-
pickle模块(以后了解)
-
open()
-
Python open() 方法用于打开一个文件,并返回文件对象,在对文件进行处理过程都需要使用到这个函数,如果该文件无法被打开,会抛出 OSError
-
注意:使用 open() 方法一定要保证关闭文件对象,即调用 close() 方法。open() 函数常用形式是接收两个参数:文件名(file)和模式(mode)。
-
常用形式
open(file, mode='r')
-
完整形式
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
- file: 必需,文件路径(相对或者绝对路径)。
- mode: 可选,文件打开模式
- buffering: 设置缓冲
- encoding: 一般使用utf8
- errors: 报错级别
- newline: 区分换行符
- closefd: 传入的file参数类型
- opener: 参见上述打开文件的模式
- mode可选参数有
模式 描述 t 文本模式 (默认)。 x 写模式,新建一个文件,如果该文件已存在则会报错。 b 二进制模式。 + 打开一个文件进行更新(可读可写)。 U 通用换行模式(Python 3 不支持)。 r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等。 r+ 打开一个文件用于读写。文件指针将会放在文件的开头。 rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等。 w 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 wb 以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 w+ 打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。 wb+ 以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等。 a 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 ab 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 a+ 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 ab+ 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 - file 对象使用 open 函数来创建,下表列出了 file 对象常用的函数
序号 方法及描述 1 file.close()关闭文件。关闭后文件不能再进行读写操作。 2 file.flush()刷新文件内部缓冲,直接把内部缓冲区的数据立刻写入文件, 而不是被动的等待输出缓冲区写入。 3 file.fileno()返回一个整型的文件描述符(file descriptor FD 整型), 可以用在如os模块的read方法等一些底层操作上。 4 file.isatty()如果文件连接到一个终端设备返回 True,否则返回 False。 5 file.next()Python 3 中的 File 对象不支持 next() 方法。返回文件下一行。 6 [file.read(size])从文件读取指定的字节数,如果未给定或为负则读取所有。 7 [file.readline(size])读取整行,包括 "\n" 字符。 8 [file.readlines(sizeint])读取所有行并返回列表,若给定sizeint>0,返回总和大约为sizeint字节的行, 实际读取值可能比 sizeint 较大, 因为需要填充缓冲区。 9 [file.seek(offset, whence])移动文件读取指针到指定位置 10 file.tell()返回文件当前位置。 11 [file.truncate(size])从文件的首行首字符开始截断,截断文件为 size 个字符,无 size 表示从当前位置截断;截断之后后面的所有字符被删除,其中 windows 系统下的换行代表2个字符大小。 12 file.write(str)将字符串写入文件,返回的是写入的字符长度。 13 file.writelines(sequence)向文件写入一个序列字符串列表,如果需要换行则要自己加入每行的换行符。
-
-
OS模块
- os 模块提供了非常丰富的方法用来处理文件和目录。常用的方法如下表所示:
序号 | 方法及描述 |
---|---|
1 | os.access(path, mode) 检验权限模式 |
2 | os.chdir(path) 改变当前工作目录 |
3 | os.chflags(path, flags) 设置路径的标记为数字标记。 |
4 | os.chmod(path, mode) 更改权限 |
5 | os.chown(path, uid, gid) 更改文件所有者 |
6 | os.chroot(path) 改变当前进程的根目录 |
7 | os.close(fd) 关闭文件描述符 fd |
8 | os.closerange(fd_low, fd_high) 关闭所有文件描述符,从 fd_low (包含) 到 fd_high (不包含), 错误会忽略 |
9 | os.dup(fd) 复制文件描述符 fd |
10 | os.dup2(fd, fd2) 将一个文件描述符 fd 复制到另一个 fd2 |
11 | os.fchdir(fd) 通过文件描述符改变当前工作目录 |
12 | os.fchmod(fd, mode) 改变一个文件的访问权限,该文件由参数fd指定,参数mode是Unix下的文件访问权限。 |
13 | os.fchown(fd, uid, gid) 修改一个文件的所有权,这个函数修改一个文件的用户ID和用户组ID,该文件由文件描述符fd指定。 |
14 | os.fdatasync(fd) 强制将文件写入磁盘,该文件由文件描述符fd指定,但是不强制更新文件的状态信息。 |
15 | [os.fdopen(fd, mode[, bufsize]]) 通过文件描述符 fd 创建一个文件对象,并返回这个文件对象 |
16 | os.fpathconf(fd, name) 返回一个打开的文件的系统配置信息。name为检索的系统配置的值,它也许是一个定义系统值的字符串,这些名字在很多标准中指定(POSIX.1, Unix 95, Unix 98, 和其它)。 |
17 | os.fstat(fd) 返回文件描述符fd的状态,像stat()。 |
18 | os.fstatvfs(fd) 返回包含文件描述符fd的文件的文件系统的信息,Python 3.3 相等于 statvfs()。 |
19 | os.fsync(fd) 强制将文件描述符为fd的文件写入硬盘。 |
20 | os.ftruncate(fd, length) 裁剪文件描述符fd对应的文件, 所以它最大不能超过文件大小。 |
21 | os.getcwd() 返回当前工作目录 |
22 | os.getcwdu() 返回一个当前工作目录的Unicode对象 |
23 | os.isatty(fd) 如果文件描述符fd是打开的,同时与tty(-like)设备相连,则返回true, 否则False。 |
24 | os.lchflags(path, flags) 设置路径的标记为数字标记,类似 chflags(),但是没有软链接 |
25 | os.lchmod(path, mode) 修改连接文件权限 |
26 | os.lchown(path, uid, gid) 更改文件所有者,类似 chown,但是不追踪链接。 |
27 | os.link(src, dst) 创建硬链接,名为参数 dst,指向参数 src |
28 | os.listdir(path) 返回path指定的文件夹包含的文件或文件夹的名字的列表。 |
29 | os.lseek(fd, pos, how) 设置文件描述符 fd当前位置为pos, how方式修改: SEEK_SET 或者 0 设置从文件开始的计算的pos; SEEK_CUR或者 1 则从当前位置计算; os.SEEK_END或者2则从文件尾部开始. 在unix,Windows中有效 |
30 | os.lstat(path) 像stat(),但是没有软链接 |
31 | os.major(device) 从原始的设备号中提取设备major号码 (使用stat中的st_dev或者st_rdev field)。 |
32 | os.makedev(major, minor) 以major和minor设备号组成一个原始设备号 |
33 | [os.makedirs(path, mode]) 递归文件夹创建函数。像mkdir(), 但创建的所有intermediate-level文件夹需要包含子文件夹。 |
34 | os.minor(device) 从原始的设备号中提取设备minor号码 (使用stat中的st_dev或者st_rdev field )。 |
35 | [os.mkdir(path, mode]) 以数字mode的mode创建一个名为path的文件夹.默认的 mode 是 0777 (八进制)。 |
36 | [os.mkfifo(path, mode]) 创建命名管道,mode 为数字,默认为 0666 (八进制) |
37 | [os.mknod(filename, mode=0600, device]) 创建一个名为filename文件系统节点(文件,设备特别文件或者命名pipe)。 |
38 | [os.open(file, flags, mode]) 打开一个文件,并且设置需要的打开选项,mode参数是可选的 |
39 | os.openpty() 打开一个新的伪终端对。返回 pty 和 tty的文件描述符。 |
40 | os.pathconf(path, name) 返回相关文件的系统配置信息。 |
41 | os.pipe() 创建一个管道. 返回一对文件描述符(r, w) 分别为读和写 |
42 | [os.popen(command, mode[, bufsize]]) 从一个 command 打开一个管道 |
43 | os.read(fd, n) 从文件描述符 fd 中读取最多 n 个字节,返回包含读取字节的字符串,文件描述符 fd对应文件已达到结尾, 返回一个空字符串。 |
44 | os.readlink(path) 返回软链接所指向的文件 |
45 | os.remove(path) 删除路径为path的文件。如果path 是一个文件夹,将抛出OSError; 查看下面的rmdir()删除一个 directory。 |
46 | os.removedirs(path) 递归删除目录。 |
47 | os.rename(src, dst) 重命名文件或目录,从 src 到 dst |
48 | os.renames(old, new) 递归地对目录进行更名,也可以对文件进行更名。 |
49 | os.rmdir(path) 删除path指定的空目录,如果目录非空,则抛出一个OSError异常。 |
50 | os.stat(path) 获取path指定的路径的信息,功能等同于C API中的stat()系统调用。 |
51 | [os.stat_float_times(newvalue]) 决定stat_result是否以float对象显示时间戳 |
52 | os.statvfs(path) 获取指定路径的文件系统统计信息 |
53 | os.symlink(src, dst) 创建一个软链接 |
54 | os.tcgetpgrp(fd) 返回与终端fd(一个由os.open()返回的打开的文件描述符)关联的进程组 |
55 | os.tcsetpgrp(fd, pg) 设置与终端fd(一个由os.open()返回的打开的文件描述符)关联的进程组为pg。 |
56 | os.tempnam([dir[, prefix]]) Python3 中已删除。返回唯一的路径名用于创建临时文件。 |
57 | os.tmpfile() Python3 中已删除。返回一个打开的模式为(w+b)的文件对象 .这文件对象没有文件夹入口,没有文件描述符,将会自动删除。 |
58 | os.tmpnam() Python3 中已删除。为创建一个临时文件返回一个唯一的路径 |
59 | os.ttyname(fd) 返回一个字符串,它表示与文件描述符fd 关联的终端设备。如果fd 没有与终端设备关联,则引发一个异常。 |
60 | os.unlink(path) 删除文件路径 |
61 | os.utime(path, times) 返回指定的path文件的访问和修改的时间。 |
62 | [os.walk(top, topdown=True[, onerror=None[, followlinks=False]]]) 输出在文件夹中的文件名通过在树中游走,向上或者向下。 |
63 | os.write(fd, str) 写入字符串到文件描述符 fd中. 返回实际写入的字符串长度 |
64 | os.path 模块 获取文件的属性信息。 |
65 | os.pardir() 获取当前目录的父目录,以字符串形式显示目录名。 |
错误处理
-
Python 有两种错误很容易辨认:语法错误和异常。
-
Python assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常。
-
异常捕捉可以使用 try/except 语句。
- 示例
try: print(1/0) except ZeroDivisionError as error: print('算式错误!', error)
-
一个 try 语句可能包含多个except子句,分别来处理不同的特定的异常。最多只有一个分支会被执行。
处理程序将只针对对应的 try 子句中的异常进行处理,而不是其他的 try 的处理程序中的异常。
-
一个except子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组
-
最后一个except子句可以忽略异常的名称,它将被当作通配符使用。你可以使用这种方法打印一个错误信息,然后再次把异常抛出。
-
try/except 语句还有一个可选的 else 子句,如果使用这个子句,那么必须放在所有的 except 子句之后。
else 子句将在 try 子句没有发生任何异常的时候执行。
-
示例
try: print(1/1) except ZeroDivisionError: print('算式错误!') else: print('算式正确!')
-
使用 else 子句比把所有的语句都放在 try 子句里面要好,这样可以避免一些意想不到,而 except 又无法捕获的异常。
-
异常处理并不仅仅处理那些直接发生在 try 子句中的异常,而且还能处理子句中调用的函数(甚至间接调用的函数)里抛出的异常
-
try-finally 语句无论是否发生异常都将执行最后的代码。
-
示例
try: print(1/1) except ZeroDivisionError: print('算式错误!') else: print('算式正确!') finally: print('执行结束!')
抛出异常
-
Python 使用 raise 语句抛出一个指定的异常。
raise [Exception [, args [, traceback]]]
-
示例
x = -1 if x<0: raise Exception('x不能小于0!当前x的值为:{}'.format(x))
-
raise 唯一的一个参数指定了要被抛出的异常。它必须是一个异常的实例或者是异常的类(也就是 Exception 的子类)。
-
如果你只想知道这是否抛出了一个异常,并不想去处理它,那么一个简单的 raise 语句就可以再次把它抛出。
-
示例
try: raise NameError('抛出name错误') except NameError: print('error') raise
自定义异常
- 你可以通过创建一个新的异常类来拥有自己的异常。异常类继承自 Exception 类,可以直接继承,或者间接继承
需补充
定义清理行为
-
ry 语句还有另外一个可选的子句,它定义了无论在任何情况下都会执行的清理行为。
-
示例
def fun(x, y): try: result = x / y except ZeroDivisionError: print('算式不正确!') else: print(result) finally: print('finally执行了')
-
以上例子不管 try 子句里面有没有发生异常,finally 子句都会执行。
-
如果一个异常在 try 子句里(或者在 except 和 else 子句里)被抛出,而又没有任何的 except 把它截住,那么这个异常会在 finally 子句执行后被抛出。
预定义的清理行为
-
一些对象定义了标准的清理行为,无论系统是否成功的使用了它,一旦不需要它了,那么这个标准的清理行为就会执行
-
关键词 with 语句就可以保证诸如文件之类的对象在使用完之后一定会正确的执行他的清理方法。
-
示例
with open("myfile.txt") as f: for line in f: print(line, end="")
-
以上这段代码执行完毕后,就算在处理过程中出问题了,文件 f 总是会关闭。
面向对象
- 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
- 方法:类中定义的函数。
- 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
- 数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
- 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
- 局部变量:定义在方法中的变量,只作用于当前实例的类。
- 实例变量:在类的声明中,属性是用变量来表示的,这种变量就称为实例变量,实例变量就是一个用 self 修饰的变量。
- 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
- 实例化:创建一个类的实例,类的具体对象。
- 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
- Python中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法。
- 对象可以包含任意数量和类型的数据。
类定义
-
语法示例
class ClassName:
. . .
类对象
-
类对象支持两种操作:属性引用和实例化。
-
属性引用使用和 Python 中所有的属性引用一样的标准语法:obj.name。
-
简单的示例
class MyClass: i = 123 def fun(): print('ok') x = MyClass print(x.i) x.fun() #输出 123 ok
-
类有一个名为 init() 的特殊方法(构造方法),该方法在类实例化时会自动调用
-
类定义了 init() 方法,类的实例化操作会自动调用 init() 方法
-
示例
class MyClass: def __init__(self, name, age): self.name = name self.age = age def fun(): print('ok') x = MyClass('tom', 12)
-
类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self。
-
self代表类的实例而不是类本身
-
实例
class MyClass: def __init__(self, name, age): self.name = name self.age = age def fun(): print('ok') def show(self): print(self) print(self.__class__) x = MyClass('tom', 12) x.show() ### 输出: <__main__.MyClass object at 0x00000232102066C8>
### -
从执行结果可以很明显的看出,self 代表的是类的实例,代表当前对象的地址,而 self.class 则指向类。
-
self 不是 python 关键字,我们把他换成 runoob 也是可以正常执行的(决定的是第一个参数的位置而不是参数名称)
类的方法
-
在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self, 且为第一个参数,self 代表的是类的实例。
-
实例
class MyClass: def __init__(self, name, age): self.name = name self.age = age def fun(): print('ok') def show(self): print(self.name) x = MyClass('tom', 12) x.show() ### 输出: tom
继承
-
Python 同样支持类的继承,如果一种语言不支持继承,类就没有什么意义。
-
语法
class DerivedClassName(BaseClassName1):
. . . -
BaseClassName(示例中的基类名)必须与派生类定义在一个作用域内。除了类,还可以用表达式,基类定义在另一个模块中时这一点非常有用
-
示例
class People(): className = 'People' def __init__(self, name, age): self.name = name self.age = age def fun1(self): print(self.name) class Student(People): className = 'Student' def __init__(self, name, age, mark): People.__init__(self, name, age) // 调用父类构造函数实现父类已有参数初始化 self.mark = mark def fun2(self): print(self.mark) p1 = Student('小明', 21, 'student') p1.fun1() p1.fun2()
多继承
-
语法
class DerivedClassName(Base1, Base2, Base3):
. . . -
需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索 即方法在子类中未找到时,从左到右查找父类中是否包含方法。
-
示例
class People(): className = 'People' def __init__(self, name, age): self.name = name self.age = age def fun1(self): print(self.name) class Funx(): className = 'Funx' def __init__(self, funx1, funx2): self.funx1 = funx1 self.funx2 = funx2 def show(self): print(self.funx1, self.funx2) class Student(People, Funx): className = 'Student' def __init__(self, name, age, funx1, funx2, mark): People.__init__(self, name, age) Funx.__init__(self, funx1, funx2) self.mark = mark def fun2(self): print(self.mark)
方法重写
-
可以在子类重写你父类的方法(也就是在子类中定义与要覆盖函数同名的函数)
-
super()函数是用于调用父类(超类)的一个方法
-
示例
class People(): className = 'People' def __init__(self, name, age): self.name = name self.age = age def fun1(self): print(self.name) class Student(People): def __init__(self, name, age, mark): People.__init__(self, name, age) self.mark = mark def fun1(self): print(self.age) p1 = Student('小明', 12, 'is a Student') p1.fun1() super(Student, p1).fun1() ### 输出: 12 小明
子类继承父类构造函数说明
-
如果在子类中需要父类的构造方法就需要显式地调用父类的构造方法,或者不重写父类的构造方法。
-
子类不重写 init,实例化子类时,会自动调用父类定义的 init。
-
示例
class People(): className = 'People' def __init__(self, name, age): self.name = name self.age = age def fun1(self): print(self.name) class Student(People): def fun1(self): print(self.age)
-
如果重写了init 时,实例化子类,就不会调用父类已经定义的 init
-
如果重写了init 时,要继承父类的构造方法,可以使用 super 关键字
-
语法
super(子类,self).__init__(参数1,参数2,....)
-
示例
class People(): className = 'People' def __init__(self, name, age): self.name = name self.age = age def fun1(self): print(self.name) class Student(People): def __init__(self, name, age, mark): super(Student, self).__init__(name, age) #相当于People.__init__(self, name, age) self.mark = mark def fun1(self): print(self.name + 's') def fun2(self): print(self.mark)
类属性与方法
-
类的私有属性
- __private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。
-
类的方法
- 在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数,self 代表的是类的实例
- self 的名字并不是规定死的,也可以使用 this,但是最好还是按照约定是用 self。
-
类的私有方法
- __private_method:两个下划线开头,声明该方法为私有方法,只能在类的内部调用 ,不能在类的外部调用。self.__private_methods。
-
类的专有方法(前后均有两个下划线)
- init : 构造函数,在生成对象时调用
- del : 析构函数,释放对象时使用
- repr : 打印,转换
- setitem : 按照索引赋值
- getitem: 按照索引获取值
- len: 获得长度
- cmp: 比较运算
- call: 函数调用
- add: 加运算
- sub: 减运算
- mul: 乘运算
- truediv: 除运算
- mod: 求余运算
- pow: 乘方
-
运算符重载
-
示例
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) print(v1, v2) ### 输出: Vector (7, 8) Vector (2, 10) Vector (5, -2)
-