Python编程学习
最后一次更新了,以后不来啦😜
python
input函数
>>> zz=input()
我心光明
>>> zz
'我心光明'
'''
长语句换行
'''
>>> total = applePrice +\
... bananaPrice +\
... pearPrice
>>> total = applePrice ,
... bananaPrice ,
... pearPrice
创建列表
使用 Python 可以很轻松地创建一个列表对象,只需将列表元素传入特定的格式或函数
中就能实现。常用的创建列表的方法有两种, 一种是使用方括号[ ]进行创建,另一种是使用 list 函数进行创建。
# 步长为正数时的切片操作
>>> mylist4=[10,20,30,40,50,60,70,80,90,100]
>>> mylist4[2:7] # 提取从第 2~8 个元素之间的元素
[30, 40, 50, 60, 70]
>>> mylist4[1:9:2] # 提取从第 1~10 个元素之间的元素,步长为 2
[20, 40, 60, 80]
# 步长为负数时的切片操作
>>> mylist4[-2:-8:-2] # 提取倒数第 1~8 个元素之间的元素,步长为 2
[90, 70, 50]
>>> mylist4[1:4:0] # 步长为 0 时会报错
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: slice step cannot be zero
>>> mylist4[:-7:-2] # 提取从结尾向左到倒数第 7 个元素前的所有元素,步长为 2
[100, 80, 60]
>>> mylist4[::-1] # 提取从右端开始到左端之间的全体元素,步长为 1,即列表反转
[100, 90, 80, 70, 60, 50, 40, 30, 20, 10]
列表常用函数和方法
使用列表方法 append、extend 和 insert 向列表对象中增添元素
(1)append
向 append 传入需要添加到列表对象的一个元素,则该元素会被追加到列表尾部。注意,append 一次只能追加一个元素。
>>> month=['January','February','March','April','May','June']
>>> month.append('July') # 使用 append 函数向列表尾部追加元素
>>> month # 查看列表内容
['January', 'February', 'March', 'April', 'May', 'June', 'July']
(2)extend
使用 extend 能够将另一个列表添加到列表末尾,相当于两个列表进行拼接。类似于字
符串拼接,两个列表对象也可以通过加号(+)进行拼接,而且 extend 得到的效果与使用
自增运算(+=)相同。
>>> month_copy= month.copy() # 创建一个列表对象 month 的副本,理由稍后解释
>>> month_copy
['January', 'February', 'March', 'April', 'May', 'June', 'July']
>>> others=['August','September','November','December']
>>> month.extend(others) # 使用 extend 函数将两个列表进行合并
>>> month
['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August',
'September', 'November', 'December']
>>> month_copy+=others # 对副本进行自增运算
>>> month_copy
['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August',
'September', 'November', 'December']
(3)insert
类似于 append,使用 insert 也能够向列表中添加一个元素。不同的是,insert 可以在指
定位置添加,就像在列表某个位置插入一个元素一样。
>>> month.insert(9,'October') # 在列表第 10 个位置上插入元素
>>> month
['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August',
'September', 'October', 'November', 'December']
>>> month.insert(20,'None') # 插入位置超出列表尾端
>>> month
['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August',
'September', 'October', 'November', 'December', 'None']
删除元素
(1)使用 del 语句删除列表元素
在 Python 中,使用 del 语句可以将对象删除,实质上 del 语句是赋值语句(=)的逆
过程,若把赋值语句看作是“向对象贴变量名标签”,则 del 语句就是“将对象上的标签撕
下来”,即将一个对象与它的变量名进行分离操作。
>>> month_copy=month.copy() # 创建一个列表对象 month 副本
>>> del month_copy[-1] # 删除副本中最后一个元素
>>> month_copy
['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August',
'September', 'October', 'November', 'December']
(2) 使用 pop 语句删除列表元素
利用元素位置可以对元素进行删除操作。将元素索引传入 pop 语句中,将会获取该元
素,并将其在列表中删除,相当于把列表中的元素抽离出来。若不指定元素位置,pop 语
句将默认使用索引−1。
>>> month_copy=month.copy() # 创建一个列表对象 month 副本
>>> month_copy.pop(3) # 获取并删除第 4 个元素
'April'
>>> del_element=month_copy.pop() # 将最后一个元素赋值给一个变量并在副本中删除
>>> del_element # 查看删除元素
'None'
>>> month_copy # 查看副本
['January', 'February', 'March', 'May', 'June', 'July', 'August', 'September',
'October', 'November', 'December']
(3)使用 remove 语句删除列表元素
除了利用元素位置进行元素删除外,还可以将指定元素进行删除。将指定元素传入
remove 语句,则列表中第一次出现的该元素会被删除。
>>> month.remove('None') # 删除列表中的元素'None'
>>> month
['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August',
'September', 'October', 'November', 'December']
修改列表元素
列表对象 month 现在已经包含 12 个月的英文字符串,或许这些字符串显得过长,可以
将月份变为缩写形式,这时需要对列表元素进行修改。
>>> month[0]='Jan' # 将第 1 个元素改为缩写形式
>>> month
['Jan', 'February', 'March', 'April', 'May', 'June', 'July', 'August',
'September', 'October', 'November', 'December']
查询列表元素位置
元素查询也是处理列表的重要操作,可以利用列表方法 index 来查询指定元素在列表
中第 1 次出现的位置索引。
>>> letter=['A','B','A','C','B','B','C','A']
>>> letter.index('C') # 查询元素“C”在列表中第 1 次出现的位置
3
# 使用 in 函数判断列表是否包含元素
>>> 'A' in letter
True
列表常用操作
-
list.count 记录某个元素在列表中出现的次数
-
list.sort 对列表中的元素进行排序,默认为升序,可以通过参数 reverse=True 进行降
序排序。结果会改变原列表内容 -
sorted 与 list.sort 作用一样,但不改变原列表内容
-
list.reverse 反转列表中的各元素
-
len 获得列表长度,即元素个数
-
+ + + 将两个列表合并为一个列表
-
∗ * ∗ 重复合并同一个列表多次
区分元组和列表
元组与列表非常相似,都是有序元素的集合,并且可以包含任意类型元素。不同的是,元组是不可变的,这说明元组一旦创建后就不能修改,即不能对元组对象中的元素进行赋值修改、增加、删除等操作。列表的可变性可能更方便处理复杂问题,例如更新动态数据等,但很多时候不希望某些处理过程修改对象内容,例如敏感数据,这时就需要用到元组的不可变性。
元组
类似于列表,创建元组只需传入有序元素即可,常用的创建方法有使用圆括号( )创建
和使用 tuple 函数创建。
1.使用圆括号( )创建
使用圆括号将有序元素括起来,并用逗号隔开,可以创建元组。注意,这里的逗号是
必须存在的,即使元组当中只有一个元素,后面也需要有逗号。在 Python 中定义元组的关
键是当中的逗号,圆括号却可以省略。
>>> mytuple1=(1,2.5,('three','four'),[True,5],False) # 使用圆括号( )创建元组
>>> mytuple1
(1, 2.5, ('three', 'four'), [True, 5], False)
>>> mytuple2=2,True,'five',3.5 # 省略圆括号
>>> mytuple2
(2, True, 'five', 3.5) # 结果自动加上圆括号
>>> empty_tuple=() # 创建空元组
>>> empty_tuple
()
2.使用 tuple 函数创建
tuple 函数能够将其他数据结构对象转换成元组类型。先创建一个列表,将列表传入
tuple 函数中,再转换成元组,即可实现创建元组。
>>> mytuple1=tuple([1,2.5,('three','four'),[True,5],False])
# 使用 tuple 函数将列表转换为元组
>>> mytuple1
(1, 2.5, ('three', 'four'), [True, 5], False)
>>> mytuple2=tuple((2,True,'five',3.5))
>>> mytuple2
(2, True, 'five', 3.5)
>>> empty_tuple=tuple()
>>> empty_tuple
()
3.元组元素提取
利用序列的索引进行访问提取和切片操作,可以提取元组中的元素和切片。
(1)元组索引访问提取
>>> mytuple3=('China','America','England','France')
>>> mytuple3[0] # 提取元组第 1 个元素
'China'
>>> mytuple3[10] # 传入的索引超出元组索引范围
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: tuple index out of range
(2)元组切片操作提取
>>> mytuple3[-2::-1] # 提取元组倒数第 2 个元素到左端之间的所有元素
('England', 'America', 'China')
>>> mytuple3[1:10] # 超出元素索引范围
('America', 'England', 'France')
4.元组解包
>>> A,B,C,D=mytuple3 # 将元组中的各元素分别赋值给对应变量
>>> A
'China'
>>> C
'England'
>>> x,y,z=1,True,'one' # 利用元组解包进行多个变量赋值
>>> x
1
>>> z
'one'
5.元组常用方法和函数
- tuple.count 记录某个元素在元组中出现的次数
- tuple.index 获取元素在元组当中第 1 次出现的位置索引
- sorted 创建对元素进行排序后的列表
- len 获取元组长度,即元组元素个数
- + + + 将两个元组合并为一个元组
- ∗ * ∗ 重复合并同一个元组为一个更长的元组
# 使用 count 函数进行元素计数
>>> mytuple4=('A','D','C','A','C','B','B','A')
>>> mytuple4.count('B')
2
#使用 index 函数获取元素在元组中第一次出现的位置索引
>>> mytuple4.index('C')
2
#使用 sorted 函数对元组元素进行排序
>>> sorted(mytuple4)
['A', 'A', 'A', 'B', 'B', 'C', 'C', 'D']
#使用 len 函数获取元组长度
>>> len(mytuple4)
8
#使用元组加法合并两个元组
>>> (1,2,3)+(4,5,6)
(1, 2, 3, 4, 5, 6)
#使用元组乘法重复合并元组
>>> (10,20,30,40)*3
(10, 20, 30, 40, 10, 20, 30, 40, 10, 20, 30, 40)
字典(dict)
创建一个字典(dict)并进行增删改查操作
在 Python 中,字典是属于映射类型的数据结构。字典包含以任意类型的数据结构作为
元素的集合,同时各元素都具有与之对应且唯一的键,字典主要通过键来访问对应的元素。
字典与列表、元组有所不同,后两者使用索引来对应元素,而字典的元素都拥有各自的键,
每个键值对都可以看成是一个映射对应关系。此外,元素在字典中没有严格的顺序关系。
由于字典是可变的,所以可以对字典对象进行元素的增删改查等基本操作。
字典中的每个元素都具有对应的键,元素就是键所对应的值,键与值共同构成一个映射关系,即键→值,键和值的这种映射关系在 Python 中具体表示为 key:value,键和值之间用冒号隔开,这里称为键值对,字典中会包含多组键值对。注意,字典中的键必须使用不可变数据类型的对象,例如数字、字符串、元组等,并且键是不允许重复的;而值则可以是任意类型的,且在字典中可以重复。
创建字典
字典中最关键的信息是含有对应映射关系的键值对,创建字典需要将键和值按规定格
式传入特定的符号或函数中,Python 中常用的两种创建字典的基本方法分别是使用花括号
{ }创建和使用函数 dict 创建。
1.使用花括号{ }创建
只要将字典中的一系列键和值按键值对的格式(key:value,即键:值)传入花括号{ }中,
并以逗号将各键值对隔开,即可实现创建字典,具体创建格式如下。
dict={key_1:value_1,key_2:value_2,…,key_n:value_n}
若在花括号{ }中不传入任何键值对,则会创建一个空字典。
>>> mydict1={'myint':1,'myfloat':3.1415,'mystr':'name',
1.使用花括号创建字典
... 'myint':100,'mytuple':(1,2,3),'mydict':{}}
# 对于重复,键采用最后出现的对应值
>>> mydict1
{'myint': 100, 'myfloat': 3.1415, 'mystr': 'name', 'mytuple': (1, 2, 3), 'mydict':
{}}
>>> empty_dict={} # 创建空字典
>>> empty_dict
{}
2.使用 dict 函数创建
dict(key_1=value_1,key_2=value_2,…,key_n=value_n)。
>>> mydict1=dict([('myint',1),('myfloat',3.1415),('mystr','name'),
...('myint',100),('mytuple',(1,2,3)),('mydict',{})])
# 使用 dict 函数转换列表对象为字典
>>> mydict1
{'myint': 100, 'myfloat': 3.1415, 'mystr': 'name', 'mytuple': (1, 2, 3), 'mydict':
{}}
>>> mydict2=dict(zero=0,one=1,two=2)
>>> mydict2
{'zero': 0, 'one': 1, 'two': 2}
>>> empty_dict=dict()
>>> empty_dict
{}
3.提取字典元素
>>> mydict3={'spring':(3,4,5),'summer':(6,7,8),'autumn':(9,10,11),'winter':(1
2,1,2)}
>>> mydict3['autumn'] # 提取键为'autumn'的对应值
(9, 10, 11)
>>> mydict3['Spring'] # 提取字典中不存在的键'Spring'所对应的值
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'Spring'
4.提取前使用 in 语句测试键是否存在
>>> 'Spring' in mydict3 # 使用 in 检查传入键是否存在
False
5.使用字典方法 get
字典方法 get 能够灵活地处理元素的提取,向 get 函数传入需要的键和一个代替值即可,
无论键是否存在。
>>> mydict3.get('summer') # 传入存在的键并返回对应值
(6, 7, 8)
>>> mydict3.get('Spring') # 仅传入不存在的键,不显示任何东西
>>> print(mydict3.get('Spring')) # 打印函数返回的结果
None
>>> mydict3.get('Spring','Not in this dict') # 传入不存在的键并返回代替值
'Not in this dict'
6.增添字典元素
直接利用键访问赋值的方式,可以向字典中增添一个元素。若需要添加多个元素,或
将两个字典内容合并,可以使用 update 方法。接下来将具体介绍这两种元素增添的方法。
(1)使用键访问赋值增添
利用字典元素提取方法传入一个新的键,并对这个新键进行赋值操作,即
dict_name[newkey]=new_value,字典中会产生新的键值对,这种赋值操作可能会因为键不
存在而出现错误
>>> country=dict(China='Beijing', # 使用 dict 函数创建字典
... America='Washington',
... Britain='London',
... French='Paris',
... Canada='Ottawa')
>>> country_copy=country.copy() # 创建一个副本字典对象
>>> country_copy['Russian']='Moscow' # 增添元素
>>> country_copy
{'China': 'Beijing', 'America': 'Washington', 'Britain': 'London', 'French':
'Paris', 'Canada': 'Ottawa', 'Russian': 'Moscow'}
(2)update
字典方法 update 能将两个字典中的键值对进行合并,传入字典中的键值对会复制添加
到调用函数的字典对象中。若两个字典中存在相同键,传入字典中的键所对应的值会替换
掉调用函数字典对象中的原有值,实现值更新的效果
>>> others=dict(Australia='Canberra',
... Japan='tokyo',
... Canada='OTTAWA')
>>> country.update(others) # 使用 update 函数增添多个元素
>>> country
{'China': 'Beijing', 'America': 'Washington', 'Britain': 'London', 'French':
'Paris', 'Canada': 'OTTAWA', 'Australia': 'Canberra', 'Japan': 'tokyo'}
7.删除字典元素
使用 del 语句可以删除某个键值对。另外,字典也包含 pop 函数,只要传入键,函数
就能将对应的值从字典中抽离,不同的是必须传入参数。
(1)使用 del 语句删除字典元素
使用 del 语句删除元素的具体格式为 del dict_name[key]
>>> country_copy=country.copy()
>>> del country_copy['Canada'] # 使用 del 删除副本字典中的元素
>>> country_copy
{'China': 'Beijing', 'America': 'Washington', 'Britain': 'London', 'French':
'Paris', 'Australia': 'Canberra', 'Japan': 'tokyo'}
(2)使用 pop 语句删除字典元素
向 pop 语句传入需要删除的键,则会返回对应的值,并在字典当中移除相应的键值对。
>>> old_value=country.pop('Canada') # 将键对应的值赋值给变量,并删除键值对
>>> old_value
'OTTAWA'
>>> country
{'China': 'Beijing', 'America': 'Washington', 'Britain': 'London', 'French':
'Paris', 'Australia': 'Canberra', 'Japan': 'tokyo'}
(3)使用 clear 删除字典元素
clear 会删除字典中的所有元素,最终会返回一个空字典
>>> country_copy=country.copy()
>>> country_copy.clear() # 清空副本字典内容
>>> country_copy
{}
8.修改字典元素
为修改字典中的某个元素,同样可以使用键访问赋值来修改,格式为 dict_name[key]=
new_value。
>>> country['Japan']='Tokyo' # 直接将新值赋值给对应元素
>>> country
{'China': 'Beijing', 'America': 'Washington', 'Britain': 'London', 'French':
'Paris', 'Australia': 'Canberra', 'Japan': 'Tokyo'}
提取键值信息
# 判断键是否存在于字典当中
>>> 'Canada' in country
False
# 获取所有键
>>> all_keys=country.keys() # 使用 keys 函数得到全部键
>>> all_keys
dict_keys(['China', 'America', 'Britain', 'French', 'Australia', 'Japan'])
# 判断值是否存在于字典当中
>>> all_values=country.values() # 使用 values 函数得到全部值
>>> all_values
dict_values(['Beijing', 'Washington', 'London', 'Paris', 'Canberra', 'Tokyo'])
>>> 'Beijing' in all_values # 判断字典是否包含值
True
>>> list(all_values) # 将值的迭代形式转换为列表
['Beijing', 'Washington', 'London', 'Paris', 'Canberra', 'Tokyo']
# 判断键值对是否存在于字典当中
>>> all_items=country.items() # 使用 items 函数得到全部键值对
>>> all_items
dict_items([('China', 'Beijing'), ('America', 'Washington'), ('Britain',
'London'), ('French', 'Paris'), ('Australia', 'Canberra'), ('Japan', 'Tokyo')])
>>> ('America','Washington') in all_items # 判断字典是否包含键值对
True
>>> list(all_items) # 将键值对迭代形式转换为列表
[('China', 'Beijing'), ('America', 'Washington'), ('Britain', 'London'),
('French', 'Paris'), ('Australia', 'Canberra'), ('Japan', 'Tokyo')]
集合(set)并进行集合运算
# 使用花括号创建可变集合
>>> myset1={'A','C','D','B','A','B'}
>>> myset1
{'C', 'D', 'B', 'A'}
# 使用函数 set 创建可变集合
>>> myset2=set([2,3,1,4,False,2.5,'one'])
>>> myset2
{False, 1, 2, 3, 4, 2.5, 'one'}
>>> empty_set=set()
>>> >>> empty_set
set()
>>> type(empty_set)
<class 'set'>
2.不可变集合 frozenset 函数
>>> myset3=frozenset([3,2,3,'one',frozenset([1,2]),True])
# 使用 frozenset 函数创建不可变集合
>>> myset3
frozenset({True, 2, 3, 'one', frozenset({1, 2})})
>>> empty_frozenset=frozenset() # 创建空不可变集合
>>> empty_frozenset
frozenset()
>>> type(empty_frozenset)
<class 'frozenset'>
集合运算
1.并集
>>> A={'足球','游泳','羽毛球','乒乓球'}
>>> B={'篮球','乒乓球','羽毛球','排球'}
>>> A|B # 使用符号'|'获取并集
{'羽毛球', '排球', '乒乓球', '足球', '篮球', '游泳'}
>>> A.union(B) # 使用集合方法 union 函数获取并集
{'羽毛球', '排球', '乒乓球', '足球', '篮球', '游泳'}
2.交集
>>> A&B # 使用符号“&”获取交集
{'乒乓球', '羽毛球'}
>>> A.intersection(B) # 使用集合方法 intersection 函数获取交集
{'乒乓球', '羽毛球'}
3.差集
>>> A-B # 使用减号“-”来获取差集
{'足球', '游泳'}
>>> A.difference(B) # 使用集合方法 difference 函数获取差集
{'足球', '游泳'}
4.异或集
>>> A^B # 获取异或集
{'足球', '排球', '游泳', '篮球'}
>>> A.symmetric_difference(B) # 使用集合方法 symmetric_difference 函数获取异或集
{'足球', '排球', '游泳', '篮球'}
集合常用函数和方法
- set.add 向可变集合当中增添一个元素
- set.update 向可变集合增添其他集合的元素,即合并两个集合
- set.pop 删除可变集合中的一个元素,当集合对象是空集时,则返回错误
- set.remove 删除可变集合中指定的一个元素
- set.clear 清空可变集合中的所有元素,返回空集
- in 使用 Python 中的 in 方法可以查询元素是否存在于集合当中
- len 获取集合当中元素的个数
- set.copy 复制可变集合的内容并创建一个副本对象
>>> myset4={'red','green','blue','yellow'}
>>> myset4_copy=myset4.copy() # 创建一个集合副本对象
>>> others={'black','white'}
# 可变集合增添元素
>>> myset4.add('orange') # 使用集合方法 add 函数增添元素
>>> myset4.update(others) # 使用集合方法 update 函数合并两个集合
>>> myset4
{'black', 'green', 'yellow', 'orange', 'white', 'blue', 'red'}
# 删除可变集合元素
>>> myset4.pop() # 使用 pop 函数从集合中抽离出一个元素
'black'
>>> myset4 # 查看抽离元素后的集合内容
{'green', 'yellow', 'orange', 'white', 'blue', 'red'}
>>> myset4.remove('yellow') # 使用 remove 函数删除指定元素
>>> myset4_copy.clear() # 使用 clear 函数将副本集合内容清空
>>> myset4_copy
set()
>>> 'green' in myset4 # 使用 in 查看集合是否包含指定元素
True
>>> len(myset4) # 使用 len 函数获取集合元素个数
5
程序流程控制语句
if
if 布尔表达式 1:
分支
>>> score = 91
>>> score >= 90 and score <= 100
True
>>> score = 91
>>> if score >= 90 and score <= 100:
… print('本次考试,成绩等级为:A')
本次考试,成绩等级为:A
多路分支(else、elif)
if 布尔表达式 1:
分支一
elif 布尔表达式 2:
分支二
else:
分支三
>>> score = 59
>>> if score < 60:
... print('考试不及格')
>>> else:
... print('考试及格')
考试不及格
for 循环
>>> for a in ['e','f','g']:
... print(a)
e f g
>>> for a in 'string':
... print(a)
s t r i n g
while
while 布尔表达式:
程序段
>>> s = 0
>>> while(s <= 1):
... print('计数:', s)
... s = s + 1
计数: 0
计数: 1
range 函数
range(5)或 range(0,5)即构造了序列 0,1,2,3,4。注意,这里包括 0,但不包括 5
range(a,b)能够返回列表[a,a+1,…,b−1](注意不包含 b)
range 函数经常和 len 函数一起用于遍历整个序列。len 函数能够返回一个序列的长度,for i in range(len(L))能够迭代整个列表 L 的元素索引。
>>> for i in range(0,5):
... print(i)
#result:0,1,2,3,4
>>> for i in range(0,6,2):
... print(i)
0,2,4 #相邻元素的间隔为 3
#直接使用 for 循环难以改变序列元素
>>> L = [1,2,3]
>>> for a in L:
... a+=1 #a 不是引用,L 中对应的元素没有发生改变
>>> print(L)
[1, 2, 3]
# 结合 range 与 len 函数来遍历序列并修改元素
>>> for i in range(len(L)):
... L[i]+=1 #通过索引访问
>>> print(L)
[2, 3, 4]
break
>>> s = 0
>>> while True:
... s+=1
... if s == 6: #满足 s 等于 6 的时候跳出循环
... break
>>> s
6
>>> for i in range(0,10):
... print(i)
... if i == 1: #当 i 等于 1 的时候跳出循环
... break
0
1
continue
>>> s = 3
>>> while s > 0:
... s = s - 1
... if s == 1: #当 s 等于 1 时跳出本次循环
... continue
... print(s)
2
0
>>> for i in range(0,3):
... if i == 1: #当 i 等于 1 时跳出本次循环
... continue
... print(i)
0
2
函数
自定义函数
>>>def my_function(parameter):
... '''打印任何传入的字符串'''
... print (parameter) # print 与 return 没有关系,也不会相互影响
... return 'parameter is '+parameter
设置函数参数
Python 中的函数参数主要有 4 种。
(1)位置参数,调用函数时根据函数定义的位置参数来传递参数。
(2)关键字参数,通过“键-值”形式加以指定,可以让函数更加清晰,容易使用,同
时也清除了参数的顺序要求。
(3)默认参数,定义函数时为参数提供的默认值,调用函数时,默认参数的值可传可
不传。注意:所有的位置参数必须出现在默认参数前,包括函数定义和调用。
(4)可变参数,定义函数时,有时候不确定调用时会传递多少个参数(不传参数也可以)。
此时,可用定义任意位置参数或者关键字参数的方法来进行参数传递,会显得非常方便。
1.默认参数
在调用内建函数的时候,往往会发现很多函数提供了默认的参数。默认参数为程序人员提供了极大的便利,特别对于初次接触该函数的人来说更是意义重大。默认参数为设置函数的参数值提供了参考。
2.任意数量的位置可变参数
定义函数时需要定义函数的参数个数,通常情况下,这个参数个数表示了函数可调用的参数个数的上限。但是也有在定义函数时无法得知参数个数的情况,在 Python 中使用 ∗ a r g s *args ∗args 和 ∗ k w a r g s *kwargs ∗kwargs 可以定义可变参数,在可变参数之前可以定义 0 到任意多个参数。注意,可变参数永远放在参数的最后面。
在定义任意数量的位置参数时需要一个星号前缀( ∗ * ∗)来表示,在传递参数的时候,可以在原有的参数后面添加 0 个或多个参数,这些参数将会被放在元组内并传入函数。任意数量的位置参数必须定义在位置参数或关键字参数之后。
>>> def exp(x,y,*args):
... print('x:',x)
... print('y:',y)
... print('args:',args)
>>> exp(1,5,66,55,'abc')
x: 1
y: 5
args: (66, 55, 'abc')
'''
定义了两个参数 x 和 y,之后定义了可变参数$*args$。
$*args$ 参数传入函数后存储在一个元组中
'''
3.任意数量的关键字可变参数
在定义任意数量的关键字可变参数时,参数名称前面需要有两个星号(
∗
∗
**
∗∗)作为前缀。
在传递的时候,可以在原有的参数后面添加任意数量的关键字可变参数,这些参数会被放
到字典内并传入函数中。带两个星号前缀的参数必须在所有带默认值的参数之后,顺序不
可以调转.
>>>def exp(x,y,*args,**kwargs):
... print('x:',x)
... print('y:',y)
... print('args:',args)
... print('kwargs:',kwargs)
>>>exp(1,2,2,4,6,a='c',b=1)
函数传入了“1,2,2,4,6,a=’c’,b=1”,总共 7 个参数。其中,1 和 2 被函数
识别为 x 和 y,“2,4,6”被识别为*args 并存储在元组[2,4,6]中,“a=’c’,b=1”被识别为**kwargs
并存储在带有关键字的字典中。
4.返回函数值
函数可以处理一些数据,并返回一个或一组值。函数返回的值称为返回值。
>>>def interest_r(money,day = 1,interest_rate= 0.05):
... income = 0
... income = money*interest_rate*day/365
... return income
5.调用自定义函数
有3种函数调用方式,分别为位置参数调用、关键字参数调用、可变参数调用。
(1) 位置参数调用
位置参数调用是函数调用最常用的方式,函数的参数严格按照函数定义时的位置传入,
顺序不可以调换,否则会影响输出结果或者直接报错。
>>>list(range(0,10,2)) # 按 start=0,stop=10,step=2 的顺序传入
[0, 2, 4, 6, 8]
>>>list(range(10,0,2)) # 调转 strart 和 stop 的顺序后传入
[]
>>>list(range(10,2,0)) # 调转全部参数的顺序后传入
Traceback (most recent call last):
File "E:\python\lib\site-packages\IPython\core\interactiveshell.py", line
2881, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-2-0b56cef3a2dc>", line 1, in <module>
list(range(10,2,0))
ValueError: range() arg 3 must not be zero
(2) 关键字参数调用
除了可以使用位置参数对函数进行调用外,还可以使用关键字参数对函数进行调用。
使用关键字参数时,可以不严格按照位置,因为解释器会自动按照关键字进行匹配。
关键字参数也可以与位置参数混用,但关键字参数必须跟在位置参数后面,否则会报
错.interest_rate 即为关键字参数.
>>>interest(10000,day=7,interest_rate=0.06)
11.506849315068493
>>>interest(10000,interest_rate=0.06,day=7)
11.506849315068493
>>>interest(interest_rate=0.06,7,money=10000)
# 位置参数必须在关键字参数前面,否则会报错
File "<ipython-input-14-1fbe6ee16ee2>", line 1
interest(interest_rate=0.06,7,money=10000)
^
SyntaxError: positional argument follows keyword argument
(3) 可变参数调用
使用
∗
a
r
g
*arg
∗arg 可变参数列表可以直接将元组或者列表转换为参数,然后传入函数
使用
∗
∗
k
w
a
r
g
s
**kwargs
∗∗kwargs 关键字参数列表可以直接将字典转换为关键字参数,然后传入函数中
>>>def user(username,age,**kwargs):
... print('username:',username,
... 'age:',age,
... 'other:',kwargs)
>>>user('john',27,city = 'guangzhou',job = 'Data Analyst')
username: john age: 27 other: {'city': 'guangzhou', 'job': 'Data Analyst'}
>>>kw={'age':27,'city':'guangzhou','job':'Data Analyst'}
>>>user('john',**kw)
username: john age: 27 other: {'city': 'guangzhou', 'job': 'Data Analyst'}
6.区分局部变量和全局变量
(1) 局部变量
在定义函数时,往往需要在函数内部对变量进行定义和赋值,在函数体内定义的变量
为局部变量。
'''
#函数体内定义了一个局部变量 sum1,所有针对该变量的操作仅在函
数体内有效
'''
>>>def sum(*arg):
... sum1 = 0
... for i in range(len(arg)):
... sum1 +=arg[i]
... return sum1
>>>sum(1,2,3,4,5)
15
>>>sum1
0
(2) 全局变量
与局部变量相对应,定义在函数体外面的变量为全局变量,全局变量可以在函数体内
被调用
>>>sum0 = 10
>>>def fun():
... sum_global=sum0+100
... return sum_global
>>>fun()
110
全局变量不能在函数体中被直接赋值
>>>sum1=0
>>>def sum(*arg):
... for i in range(len(arg)):
... sum1 +=arg[i]
... return sum1
>>>sum(1,2,3,4)
File "<ipython-input-15-64d994261251>", line 6, in <module>
sum(1,2,3,4)
File "<ipython-input-15-64d994261251>", line 4, in sum
sum1 +=arg[i]
UnboundLocalError: local variable 'sum1' referenced before assignment
创建并使用匿名函数
Python 允许使用 lambda 语句创建匿名函数,也就是说函数没有具体的名称。
当需要定义一个功能简单但不经常使用的函数来执行脚本时,就可以使用 lambda 定义匿名函数,从而省去定义函数的过程。
lambda 语句中,冒号前是函数参数,若有多个函数须使用逗号分隔;冒号后是返回值。
def 语句也可以创建一个函数对象,只是使用 lambda 语句创建的函数对象没有名称。
>>>example = lambda x : x**3
>>>print(example)
<function <lambda> at 0x000001EA16DCA730>
>>>example(2)
8
掌握其他常用高阶函数
除了 lambda 函数外,Python 中还有其他常用的高阶内置函数,如 map 函数、fib 函数
和 filter 函数
1.map 函数
>>>def add(x):
... x += 3
... return x
>>>numbers = list(range(10))
>>>num1 = list(map(add,numbers))
>>>num2 = list(map(lambda x:x+3,numbers))
2.fib 函数
fib 函数是一个递归函数,最典型的递归示例之一就是斐波那契数列。
>>>def fib(n):
... if n <=2 :
... return 2
... else:
... return fib(n-1)+fib(n-2)
>>>f = fib(10)
>>>print(f)
110
3.filter 函数
filter 函数是 Python 内置的另一个常用的高阶函数。filter 函数接收一个函数 func 和一
个 list,这个函数 func 的作用是对每个元素进行判断,通过返回 True 或 False 来过滤掉不
符合条件的元素,符合条件的元素组成的新 list
>>>list(filter(lambda x:x%2==1, [1, 4, 6, 7, 9, 12, 17]))
>>>s = list(filter(lambda c:c!='o','i love python and R!'))
>>>s = ''.join(s) # 变为字符型
>>>print(s)
面向对象编程
class 类名:
属性列表
方法列表
>>>class Cat():
... """一次模拟猫咪的简单尝试"""
... name = 'tesila' # 属性
... age = 3 # 方法
... def sleep(self):
... """模拟猫咪被命令睡觉"""
... print('%d 岁的%s 正在沙发上睡懒觉。'%(self.age, self.name))
... def eat(self,food):
... """模拟猫咪被命令吃东西"""
... self.food = food
... print('%d 岁的%s 在吃%s'%(self.age, self.name,self.food))
绑定 self
Python 的类的方法和普通的函数有一个很明显的区别,就是类的方法必须有个额外的
参数(self),并且在调用这个方法的时候不必为这个参数赋值。Python 类方法的这个特别
参数指代的是对象本身,而按照 Python 惯例,它用 self 来表示。
>>>class Cat():
... def sleep(self):
... print(self)
>>>new_cat = Cat()
>>>print(new_cat.sleep())
<__main__.Cat object at 0x00000000098656D8>
self 代表当前对象的地址,能避免非限定调用时找不到访问对象或变量。当调用 sleep
等函数时,会自动把该对象的地址作为第 1 个参数传入;如果不传入地址,程序将不知道
该访问哪个对象。
self 名称也不是必需的,在 Python 中,self 不是关键字,可以定义成 a、b 或其他名字。
>>>class Test:
... def prt(my_address):
... print(my_address)
... print(my_address.__class__)
>>>t = Test()
>>>t.prt()
<__main__.Test object at 0x000000000980AF60>
<class '__main__.Test'>
简而言之,self 需要定义,但是在调用时会自动传入;self 的名字并不是规定死的,但
最好还是按照约定使用 self。
- getitem__和__setitem,像普通的方法 clear、keys 和 values 一样,它只是重定向到字
典,返回字典的值。通常不用直接调用它,而使用相应的语法让 Python 来调用__setitem。
每个文件类型都可以拥有一个处理器类,这些类知道如何从一个特殊的类得到元数据。一
旦知道了某些属性(如文件名和位置),处理器类就知道如何自动地得到其他属性。 - __repr__是一个专有的方法,只有当调用 repr(instance)时被调用。repr 函数是一个内置
函数,它用返回一个对象的字符串表示。 - __cmp__在比较类实例时被调用,通常可以通过使用“==”比较任意两个 Python 对象,
不只是类实例。 - __len__在调用 len(instance)时被调用。len 是 Python 的内置函数,可以返回一个对象的
长度。字符串对象返回的是字符个数;字典对象返回的是关键字的个数;列表或序列返回
的是元素的个数。对于类和对象,定义__len__方法,可以自己定义长度的计算方式,然后
调用 len(instance),Python 则会将调用定义的__len__专用方法。 - __del__在调用 del instance[key]时调用,它会从字典中删除单个元素。
- __call__方法让一个类表现得像一个函数,可以直接调用一个类实例。
- __setitem__方法可以让任何类像字典一样保存键-值对。
- __getitem__方法可以让任何类表现得像一个序列。
# -*-coding:utf-8-*-
class Car(): # 创建类
"""一次模拟汽车的简单尝试"""
wheelNum = 4 # 增加属性
color = 'red'
def getCarInfo(self,name): # 定义 getCarInfo 函数
self.name = name
print(self.name,'有%d 个车轮, 颜色是%s。'%(self.wheelNum,self.color))
def run(self): # 定义 run 函数
print('车行驶在学习的大道上。')
new_car = Car() # 调用 Car 类
print(new_car.getCarInfo('Land Rover')) # 调用 getCarInfo 函数
print(new_car.run())
__init__是类的一个特殊的方法,每当根据类创建新实例时,Python 都会自动运行它。
这就是一个初始化手段,Python 中的__init__方法用于初始化类的实例对象。__init__方法
的作用在一定程度上与 C++的构造函数相似,但并不等于。使用 C++的构造函数,可创建
一个类的实例对象,而 Python 执行__init__方法时,实例对象已被构造出来。__init__方法
会在对象构造出来后自动执行,所以可以用于初始化所需要的数据属性。
>>>class Cat():
... """再次模拟猫咪的简单尝试"""
... # 构造器方法
... def __init__(self,name,age):
... self.name = name # 属性
... self.age = age
... def sleep(self):
... """模拟猫咪被命令睡觉"""
... print('%d 岁的%s 正在沙发上睡懒觉。'%(self.age, self.name))
... def eat(self,food):
... """模拟猫咪被命令吃东西"""
... self.food = food
... print('%d 岁的%s 在吃%s'%(self.age, self.name,self.food))
代码把属性 name 和 age 放入了KaTeX parse error: Expected group after '_' at position 1: _̲_init__方法中并进行初始化,通过实参向 Cat 类传
递名字和年龄。self 会自动传递,因此创建对象时只需给出后两个形参(name 和 age)的
值即可。
删除对象
创建对象时,默认调用构造方法。当删除一个对象时,同样也会默认调用一个方法,
这个方法为析构方法。__del__是类的另一个特殊的方法,当使用 del 语句删除对象时,会
调用它本身的析构函数。另外,当对象在某个作用域中调用完毕,跳出其作用域的同时,
析构函数也会被调用一次,释放内存空间。
>>>class Animal():
... # 构造方法
... def __init__(self):
... print( '---构造方法被调用---')
... # 析构方法
... def __del__(self):
... print( '---析构方法被调用---')
>>>cat = Animal()
---构造方法被调用---
>>>print(cat)
<__main__.Animal object at 0x0000000009851400>
>>>del cat
---析构方法被调用---
>>>print(cat)
Traceback (most recent call last):
File "<ipython-input-43-7c3364e51d98>", line 1, in <module>
print(cat)
NameError: name 'cat' is not defined
>>>class Cat():
... def __init__(self,name,age):
... self.name = name
... self.age = age
... def sleep(self):
... print('%d 岁的%s 正在沙发上睡懒觉。'%(self.age, self.name))
... def eat(self,food):
... self.food = food
... print('%d 岁的%s 在吃%s。'%(self.age, self.name,self.food))
>>>cat1 = Cat('Tom', 3) # 创建对象
>>>cat2 = Cat('Jack',4)
>>>print('Cat1 的名字为:',cat1.name) # 访问对象的属性
Cat1 的名字为: Tom
>>>print('Cat2 的名字为:',cat2.name)
Cat2 的名字为: Jack
>>>print(cat1.sleep()) # 访问对象的方法
3 岁的 Tom 正在沙发上睡懒觉。
>>>print(cat2.eat('fish'))
4 岁的 Jack 在吃 fish。
对象方法的引用
>>>cat1 = Cat('Tom', 3)
>>>sleep = cat1.sleep
>>>print(sleep())
3 岁的 Tom 正在沙发上睡懒觉。
>>>cat2 = Cat('Jack',4)
>>>eat = cat2.eat
>>>print(eat('fish'))
4 岁的 Jack 在吃 fish。
私有化方法
>>>class Cat():
... def __init__(self,name,age):
... self.__name = name
... self.__age = age
... def sleep(self):
... """模拟猫咪被命令睡觉"""
... print('%d 岁的%s 正在沙发上睡懒觉。'%(self.__age, self.__name))
... def eat(self,food):
... """模拟猫咪被命令吃东西"""
... self.__food = food
... print('%d 岁的%s 在吃%s。'%(self.__age, self.__name,self.__food))
... def getAttribute(self): ... return self.__name,self.__age
>>>cat1 = Cat('Tom', 3) # 创建对象
>>>cat2 = Cat('Jack',4)
>>>print('Cat1 的名字为:',cat1.name) # 从外部访问对象的属性,会发现访问不了
Traceback (most recent call last):
File "<ipython-input-57-c85f1f024f81>", line 1, in <module>
print('Cat1 的名字为:',cat1.name)
AttributeError: 'Cat' object has no attribute 'name'
>>>print('Cat2 的名字为:',cat2.name)
Traceback (most recent call last):
File "<ipython-input-58-526f8a44b064>", line 1, in <module>
print('Cat2 的名字为:',cat2.name)
AttributeError: 'Cat' object has no attribute 'name'
>>>print(cat1.sleep()) # 只能通过设置好的接口函数来访问对象
3 岁的 Tom 正在沙发上睡懒觉。
>>>print(cat2.eat('fish'))
4 岁的 Jack 在吃 fish。
>>>print(cat1.getAttribute()
>>>('Tom', 3)
现在,在程序外部直接访问私有数据属性是不允许的,只能通过设定好的接口函数去
调取对象的信息。不过,通过双下划线实现的私有化其实是“伪私有化”,实际上还要从外
部访问这些私有数据属性
访问私有化属性
>>>print(cat1._Cat__name)
Tom
>>>print(cat1._Cat__age)
3
Python 使用 name_mangling 技术将__membername替换成 _class_membername ,在外部
使用原来的私有成员时,会提示无法找到,而执行 cat1._Cat__name 则可以访问。简而言之,
想让其他人无法访问对象的方法和数据属性是不可能的,程序开发人员也不应该随意使用
从外部访问私有成员的 name_mangling 技术。
生成迭代器
>>>for element in [1,2,3]:
... print(element)
>>>for element in (1,2,3):
... print(element)
>>>for key in {'one':1,'two':2}:
... print(key)
>>>for char in '123':
... print(char)
>>>for line in open('myfile.txt'):
... print(line)
迭代器有两个基本的函数,即 iter 函数和 next 函数。假如 for语句在容器对象上调用 iter 函数,则该函数会返回一个定义 next 函数的迭代对象,它会在容器中逐一访问元素。当容器遍历完毕,next 函数找不到后续元素时,会引发一个StopIteration 异常,告知 for 循环终止.
>>>L = [1,2,3]
>>>it = iter(L)
>>>it
<list_iterator at 0xa9e0630>
>>>next(it)
1
>>>next(it)
2
>>>next(it)
3
>>>next(it)
Traceback (most recent call last):
File "<ipython-input-9-2cdb14c0d4d6>", line 1, in <module>
next(it)
StopIteration
迭代器(Iterator)是一个可以记住遍历的位置的对象,从第 1 个元素被访问开始,直
到所有元素被访问完结束
>>>class Cat():
... def __init__(self,name,age):
... self.name = name
... self.age = age
... self.info = [self.name,self.age]
... self.index = -1
... def getName(self):
... return self.name
... def getAge(self):
... return self.age
... def __iter__(self):
... print('名字 年龄')
... return self
... def next(self):
... if self.index == len(self.info)-1:
... raise StopIteration
... self.index += 1
... return self.info[self.index]
>>>newcat = Cat('coffe', 3) # 创建对象
>>>print(newcat.getName()) # 访问对象的属性
coffe
>>>iterator = iter(newcat.next,1) # 调用迭代函数来输出对象的属性
>>>for info in iterator:
... print(info)
coffe
3
返回迭代器
1.yield
在 Python 中,使用生成器(Generator)可以很方便地支持迭代器协议。生成器是一个
返回迭代器的函数,它可以通过常规的 def 函数来定义,但是不用 return 语句返回,而是
用 yield 语句一次返回一个结果。一般的函数生成值后会退出,但生成器函数在生成值后会
自动挂起暂停执行状态并保存状态信息。这些信息在函数恢复时将再度生效,通过在每个
结果之间挂起和继续它们的状态自动实现迭代协议。
这里用一个示例(yield 实现斐波那契数列)来区分有 yield 语句和没有 yield 语句的情
况,对生成器进一步了解
>>>import sys
>>>def fibonacci(n,w=0):
... a, b, counter = 0, 1, 0
... while True:
... if (counter > n):
... return
... yield a
... a, b = b, a + b
... print('%d,%d' % (a,b))
... counter += 1
>>>f = fibonacci(10,0) # f 是一个迭代器,由生成器返回生成
>>>while True:
... try:
... print (next(f), end=" ")
... except :
... sys.exit()
0 1,1
1 1,2
1 2,3
2 3,5
3 5,8
5 8,13
8 13,21
13 21,34
21 34,55
34 55,89
55 89,144
>>>import sys
>>>def fibonacci(n,w=0):
... a, b, counter = 0, 1, 0
... while True:
... if (counter > n):
... return
... # yield a # 不执行 yield 语句
... a, b = b, a + b
... print('%d,%d' % (a,b))
... counter += 1
>>>f = fibonacci(10,0) # f 是一个迭代器,由生成器返回生成
>>>while True:
... try:
... print (next(f), end=" ")
... except :
... sys.exit()
1,1
1,2
2,3
3,5
5,8
8,13
13,21
21,34
34,55
55,89
89,144
在调用生成器并运行的过程中,每次遇到 yield 时,函数都会暂停并保存当前所有运行
信息,返回 yield 的值,并在下一次执行 next 函数时从当前位置继续运行。
继承父类属性和方法
1.继承
面向对象编程带来的好处之一是代码的重用,实现这种重用的方法之一是继承机制。
继承(Inheritance)是两个类或多个类之间的父子关系,子类继承了父类的所有公有数据属
性和方法,并且可以通过编写子类的代码扩充子类的功能。继承实现了数据属性和方法的
重用,减少了代码的冗余度。
在程序中,继承描述的是事
在 Python 中,继承有以下一些特点。
(1)在继承中,基类初始化方法__init__不会被自动调用。如果希望子类调用基类的
__init__方法,需要在子类的__init__方法中显示调用它。这与 C++和 C#区别很大。
(2)在调用基类的方法时,需要加上基类的类名前缀,且带上 self 参数变量。注意,
在类中调用在该类中定义的方法是不需要 self 参数的。
(3)Python 总是首先查找对应类的方法,如果在子类中没有对应的方法,Python 才会
在继承链的基类中按顺序查找。
(4)在 Python 继承中,子类不能访问基类的私有成员。
添加继承方法
>>>class Cat():
... def __init__(self):
... self.name = '猫'
... self.age = 4
... self.info = [self.name,self.age]
... self.index = -1
... def run(self):
... print( self.name,'--在跑')
... def getName(self):
... return self.name
... def getAge(self):
... return self.age
... def __iter__(self):
... print('名字 年龄')
... return self
... def next(self):
... if self.index == len(self.info)-1:
... raise StopIteration
... self.index += 1
... return self.info[self.index]
>>>class Bosi(Cat):
... def setName(self, newName):
... self.name = newName
... def eat(self):
... print( self.name,'--在吃')
...
>>>bs = Bosi() # 创建对象
>>>print( 'bs 的名字为:',bs.name) # 继承父类的属性和方法
bs 的名字为: 猫
>>>print( 'bs 的年龄为:',bs.age)
bs 的年龄为: 4
>>>print(bs.run())
猫 --在跑
>>>bs.setName('波斯猫') # 子类的属性和方法
>>>bs.eat()
波斯猫 --在吃
>>>iterator = iter(bs.next,1) # 迭代输出父类的属性
>>>for info in iterator:
... print(info)
猫4
代码中定义了 Bosi 类的父类 Cat,将猫共有的属性和方法都放到父类中,子类仅仅
需要向父类传输数据属性。这样做可以很轻松地定义其他基于 Cat 类的子类。因为假如有
数百只猫,使用继承的方法可以大大减少代码量,且当需要对全部猫整体修改时,仅修改
Cat 类即可。Bosi 类的__init__函数中显示调用了 Cat 类的__init__函数,并向父类传输数据,
这里注意要加 self 参数
在继承里面不能继承父类的私有属性,所以也不用担心父类和子类出现因继承造成的
重名情况。
不能继承父类的私有属性
>>>class animal():
... def __init__(self,age):
... self.__age = age
... def print2(self):
... print(self.__age)
>>>class dog(animal):
... def __init__(self,age):
... animal.__init__(self,age)
... def print2(self):
... print(self.__age)
>>>a_animal = animal(10)
>>>a_animal.print2()
10
>>>a_dog = dog(10)
>>>a_dog.print2() # 程序报错
AttributeError: 'dog' object has no attribute '_dog__age'
多继承
如果有多个父类,则父类名需要全部写在括号里,这种情况称为多继承,格式为 Class
子类名(父类名 1,父类名 2,···)
>>>class A(object): # 定义一个父类
... def __init__(self):
... print (" ->Input A")
... print (" <-Output A")
>>>class B(A): # 定义一个子类
... def __init__(self):
... print (" -->Input B")
... A.__init__(self)
... print (" <--Output B")
>>>class C(A): # 定义另一个子类
... def __init__(self):
... print (" --->Input C")
... A.__init__(self)
... print (" <---Output C")
>>>class D(B, C): # 定义一个子类
... def __init__(self):
... print ("---->Input D")
... B.__init__(self)
... C.__init__(self)
... print ("<----Output D")
>>>d = D() # Python 中是可以多继承的,子类会继承父类中的方法、属性
---->Input D
-->Input B
->Input A
<-Output A
<--Output B
--->Input C
->Input A
<-Output A
<---Output C
<----Output D
>>>issubclass(C,B) # 判断一个类是不是另一个类的子孙类
False
>>>issubclass(C,A)
True
面向对象的三大特性是指重载、封装和多态。
1.重载
所谓重载,就是子类中有一个和父类名字相同的方法,子类中的方法会覆盖父类中同
名的方法
>>>class Cat:
... def sayHello(self):
... print("喵-----1")
>>>class Bosi(Cat):
... def sayHello(self):
... print("喵喵----2")
>>>bosi = Bosi()
>>>bosi.sayHello() # 子类中的方法会覆盖父类中同名的方法
喵喵----2
2.封装
既然 Cat 实例本身就拥有这些数据,要访问这些数据,就没有必要从外部的函数去访
问,可以直接在 Cat 类的内部定义访问数据的函数。这样,就把数据给“封装”起来了。
封装(Encapsulation)就是将抽象得到的数据和行为(或功能)相结合,形成一个有
机的整体(即类)。封装的目的是增强安全性和简化编程,使用者不必了解具体的实现细节,
而只是通过外部接口和特定的访问权限来使用类即可。简而言之,就是将内容封装到某个
地方,以后再去调用被封装在某处的内容。
3.多态
多态性(Polymorphism)是允许将父对象设置成和一个或多个它的子对象相等的技术,
比如 Car=Land_Rover。多态性使得能够利用同一类(父类)类型的指针来引用不同类的对
象,以及根据所引用对象的不同,以不同的方式执行相同的操作。
Python 是动态语言,可以调用实例方法,不检查类型,只需要方法存在,参数正确就
可以调用,这就是与静态语言(例如 Java)最大的差别之一,表明了动态(运行时)绑定
的存在。
文件基础
打开文件
>>>f = open('e_digits.txt', 'r')
读取文件
>>> f = open('e_point.txt', 'r') # 打开 e_point.txt 文件并定义变量 f
>>>txt = f.read() # 阅读文件 e_point.txt 的内容并赋值变量 txt
>>>print(txt) # 输出文件 e_point.txt 的内容
>>>2.7182818284
5904523536
0287471352
关闭文件
>>>f .close()
使用 with 语句读取文件
使用 with 语句读取文件
在文件读取的过程中,一旦程序抛出 IOError 错误,后面的 close 函数将不会被调用。
所以,在程序运行过程中,无论是否出错,都要确保能正常关闭文件,可以使用 try…finally…
结构实现
>>>try:
... f = open('e_point.txt', 'r')
... print(f.read())
>>>finally:
... if f:
... f.close()
使用 with 语句可以很好地处理上下文环境产生的异常,会自动调用 close
函数
相对文件路径
>>>with open('text_file\e_point.txt', 'r') as f:
... print(f.read())
绝对文件路径
>>>with open(r'C:\Users\45543\Desktop\ text_file\e_point.txt', 'r') as f:
... print(f.read())
在绝对路径前面加了 r,这是因为在 Window 系统下,读取文件可以用反斜杠
(\),但是在字符串中反斜杠被当作转义字符来使用,文件路径可能会被转义,所以需要在
绝对文件路径前添加字符 r,显式声明字符串不用转义。
也可以采用双反斜杠(\)的方式表示路径,此时不需要声明字符串,如下代码 所示。
双反斜杠方式
>>>with open('C:\\Users\\45543\\Desktop\\ text_file\\e_point.txt', 'r') as f:
... print(f.read())
创建含有文件数据的列表
读取文件时,常常需要检查其中的每一行,可能需要在文件中查找特定的信息,或者
需要以某种方式修改文件中的文本,此时可以对文件对象使用 for 循环
>>>file_name = 'e_point.txt'
>>>with open(file_name, 'r') as f:
... for line_t in f:
... print(line_t)
2.7182818284
5904523536
0287471352
消除换行符
>>>file_name = 'e_point.txt'
>>>with open(file_name, 'r') as f:
... for line_t in f:
... print(line_t.rstrip())
2.7182818284
5904523536
0287471352
read 函数可以读取整个文件的内容,但是读取的内容将存储到一个字符串的变量中
>>>with open('e_point.txt') as f:
... txts = f.read()
>>>print(type(txt))
<class 'str'>
>>>print(txt)
2.7182818284
5904523536
0287471352
如果需要将读取的文件存储到一个列表里面,可以使用 readlines 函数。该函数可以实
现按行读取整个文件内容,然后将读取的内容存储到一个列表里面
>>>with open('e_point.txt') as f:
... txts = f.readlines()
>>>print(type(txts))
<class 'list'>
>>>print(txts)
['2.7182818284\n', '5904523536\n', '0287471352\n']
打印 readlines 函数存储的数据
>>> with open('e_point.txt') as f:
>>> ... txts = f.readlines()
>>>for txt in txts:
... print(txt.strip())
2.7182818284
5904523536
0287471352
此外,Python 还提供了 readline 函数,此函数可以实现每次读取文件的一行,通常也
是将读取到的一行内容存储到一个字符串变量中,返回 str 类型
>>>with open('e_point.txt') as f:
... txt = f.readline()
>>>print(type(txt))
<class 'str'>
>>>print(txt)
2.7182818284
数据写入文件
在 Python 的 open 函数中,标识符可指定文件打开模式,如果需要将数据写入文件,
只需要将标识符设置为写入模式(w)即可。
如果要写入的文件不存在,那么 open 函数将自动创建文件。要注意的是,如果文件已
经存在,那么以写入模式写入文件时会先清空该文件
>>>file_name = 'words.txt'
>>>f = open(file_name, 'w')
>>>f.write('Hello, world!')
>>>f.close()
标识符 w 和 wb 表示写文本文件和写二进制文件(在 r 后面添加 b 表
示要读二进制数据)。如果需要将数值型数据写入文本文件,必须先用 str 函数将数值型数
据转换为字符串格式
>>> file_name = 'data.txt'
>>> f = open(file_name, 'w')
>>> data = list(range(1,11))
>>> f.write(data)
Traceback (most recent call last):
File "Ch7_read.py", line 12, in <module>
f.write(data)
TypeError: write() argument must be str, not list
>>>f.write(str(data))
>>>f.close()
当写入多行数据的时候,write 函数不会自动添加换行符号,此时会出
现几行数据挤在一起的情况
>>>file_name = 'words.txt'
>>>f = open(file_name, 'w')
>>>f.write('Hello, world!')
>>>f.write('I love Python!')
>>>f.close()
Hello, world! I love Python!
为了将行与行数据进行区分,需要在 write 语句内添加换行符号(\n)
>>>file_name = 'words.txt'
>>>f = open(file_name, 'w')
>>>f.write('Hello, world!\n')
>>>f.write('I love Python!\n')
>>>f.close()
Hello, world!
I love Python!
使用 with 语句写入.txt 文件
>>>file_name = 'words.txt'
>>>with open(file_name, 'w') as f:
... f.write('Hello, world!\n')
... f.write('I love Python!\n')
读取 CSV 数据
>>>import csv
file_name = 'C:\\Users\\45543\\Desktop\\iris.csv'
>>>with open(file_name, 'r') as f:
... reader = csv.reader(f)
... iris = [iris_item for iris_item in reader]
>>>print(iris)
[['', 'Sepal.Length', 'Sepal.Width', 'Petal.Length', 'Petal.Width', 'Species'],
['1', '5.1', '3.5', '1.4', '0.2', 'setosa'],
['2', '4.9', '3', '1.4', '0.2', 'setosa'],
['3', '4.7', '3.2', '1.3', '0.2', 'setosa'],
…]
读取 Name 列的内容
>>>with open(file_name, 'r') as f:
... reader = csv.DictReader(f)
... column = [iris_item['Sepal.Length'] for iris_item in reader]
>>>print(column)
['5.1', '4.9', '4.7', '4.6', '5', '5.4',…]
写入.csv 文件
>>>import csv
file_name = 'C:\\Users\\45543\\Desktop\\test.csv'
>>>with open(file_name, 'w', newline = '') as f:
... write_csv = csv.writer(f)
... write_csv.writerow(iris)
查询操作系统
>>>import os
>>>os.name # 查询操作系统名称
‘nt’
>>>os.sep # 查询文件路径的分隔符
‘\\’
>>>os.linesep # 查询当前系统使用的行终止符
'\r\n'
查询工作路径
>>>path = os.getcwd() # 查询当前工作目录,并赋值给 path
>>>print(path)
C:\\Users\\45543
创建与删除目录
>>> file_name = 'C:\\Users\\45543\\Desktop\\my_file'
>>> os.mkdir(file_name) # 创建文件夹
>>> os.rmdir(file_name) # 删除文件夹
- os.path.isdir(name) 判断 name 是不是目录,不是目录就返回 False
- os.path.isfile(name) 判断 name 这个文件是否存在,不存在就返回 False
- os.path.exists(name) 判断是否存在文件或目录 name
- os.path.getsize(name) 获得文件大小,如果 name 是目录,则返回 0L
- os.path.abspath(name) 获得绝对路径
- os.path.isabs() 判断是否为绝对路径
- os.path.normpath(path) 规范 path 字符串形式
- os.path.split(name)
分隔文件名与目录(事实上,如果完全使用目录,它也会将最后一个目录
作为文件名而使其分隔开,同时它不会判断文件或目录是否存在) - os.path.splitext() 分离文件名和扩展名
- os.path.join(path,name) 连接目录与文件名或目录
- os.path.basename(path) 返回文件名
- os.path.dirname(path) 返回文件路径
- os.path.split() 返回一个路径下的目录名和文件名
- os.path.isfile()
- os.path.isdir()
分别检验给出的路径是一个目录还是文件 - os.path.existe() 检验给出的路径是否真的存在
移动文件或文件夹
使用 shutil.move 函数可以将指定的文件或文件夹移动到目标路径下,返回值是移动后
的文件绝对路径字符串
shutil.copyfile(src,dst)可以从 src 文件复制内容(不包含元数据)到 dst 文件。dst 必须
是完整的目标文件名
《python编程基础》 张健 张良均 主编 何燕 张敏 姜鹏辉 副主编