最新python入门到精通_python入门到精通 csdn

score = 77

if score>=90 and score<=100:
    print('本次考试,等级为A')
elif score>=80 and score<90:
    print('本次考试,等级为B')
elif score>=70 and score<80:
    print('本次考试,等级为C')
elif score>=60 and score<70:
    print('本次考试,等级为D')
elif score>=0 and score<60:
    print('本次考试,等级为E')

2. 注意点


* 可以和else一起使用

 

if 性别为男性:
输出男性的体重

elif 性别为女性:
输出女性的体重

else:
第三种性别的体重

 说明:


	+ 当 “性别为男性” 满足时,执行 “输出男性的体重”的相关代码
	+ 当 “性别为男性” 不满足时,如果 “性别为女性”满足,则执行 “输出女性的体重”的相关代码
	+ 当 “性别为男性” 不满足,“性别为女性”也不满足,那么久默认执行else后面的代码,即 “第三种性别的体重”相关代码



> 
> elif必须和if一起使用,否则出错
> 
> 
> else 一般用在最后,即所有条件都不满足时使用
> 
> 
> 


4. if 实现三目运算操作


a if a > b else b


如果 a > b的条件成立,三目运算的结果是a,否则就是b


##### 2.6 if语句的嵌套


if嵌套


通过学习if的基本用法,已经知道了


* 当需要满足条件去做事情的这种情况需要使用if
* 当满足条件时做事情A,不满足条件做事情B的这种情况使用if-else


想一想:



> 
> 坐火车或者地铁的实际情况是:先进行安检如果安检通过才会判断是否有车票,或者是先检查是否有车票之后才会进行安检,即实际的情况某个判断是再另外一个判断成立的基础上进行的,这样的情况该怎样解决呢?
> 
> 
> 


答:



> 
> if嵌套
> 
> 
> 


1. if嵌套的格式



if 条件1:

    满足条件1 做的事情1
    满足条件1 做的事情2

    if 条件2:
        满足条件2 做的事情1
        满足条件2 做的事情2

* 说明
	+ 外层的if判断,也可以是if-else
	+ 内层的if判断,也可以是if-else
	+ 根据实际开发的情况,进行选择


2. if嵌套的应用


demo:



ticket = 1 # 用1代表有车票,0代表没有车票
knife_length = 9 # 刀子的长度,单位为cm

if ticket == 1:
print(“有车票,可以进站”)
if knife_length < 10:
print(“通过安检”)
print(“终于可以见到Ta了,美滋滋~~~”)
else:
print(“没有通过安检”)
print(“刀子的长度超过规定,等待警察处理…”)
else:
print(“没有车票,不能进站”)
print(“亲爱的,那就下次见了”)


结果1:ticket = 1;knife\_length = 9



有车票,可以进站
通过安检
终于可以见到Ta了,美滋滋~~~

结果2:ticket = 1;knife\_length = 20



有车票,可以进站
没有通过安检
刀子的长度超过规定,等待警察处理...

结果3:ticket = 0;knife\_length = 9



没有车票,不能进站
亲爱的,那就下次见了

结果4:ticket = 0;knife\_length = 20



没有车票,不能进站
亲爱的,那就下次见了

应用:猜拳游戏


1. 强化 多个条件 的 逻辑运算
2. 体会 import 导⼊模块(“⼯具包”)的使⽤
3. **需求**



  1. 从控制台输⼊要出的拳 —— ⽯头(1)/剪⼑(2)/布(3)
  2. 电脑 随机 出拳 —— 先假定电脑只会出⽯头,完成整体代码功能
  3. ⽐较胜负

2. 参考代码:



import random

player = input(‘请输入:剪刀(0) 石头(1) 布(2):’)

player = int(player)

产生随机整数:0、1、2 中的某一个

computer = random.randint(0,2)

用来进行测试

#print(‘player=%d,computer=%d’,(player,computer))

if ((player == 0) and (computer == 2)) or ((player ==1) and (computer == 0)) or ((player == 2) and (computer == 1)):
print(‘获胜,哈哈,你太厉害了’)
elif player == computer:
print(‘平局,要不再来一局’)
else:
print(‘输了,不要走,洗洗手接着来,决战到天亮’)


随机数的处理


* 在 Python 中,要使⽤随机数,⾸先需要导⼊ 随机数 的 模块 —— “⼯具包”

 

import random

* 导⼊模块后,可以直接在 模块名称 后⾯敲⼀个 . 然后按 Tab 键,会提示该模块中包含的所有函数
* random.randint(a, b) ,返回 [a, b] 之间的整数,包含 a 和 b


##### 2.7 循环语句的介绍


1. 生活中的循环场景


跑道


2. 软件开发中循环的使用场景


跟女神告白,说一万遍"渣女,分手吧"



print("不爱了,分手吧")
print("不爱了,分手吧")
print("不爱了,分手吧")
...(还有99997遍)...

使用循环语句一句话搞定



i = 0
while i < 10000:
    print("不爱了,分手吧")
    i += 1

3. 小总结


* while和if的用法基本类似,区别在于:if 条件成立,则执行一次; while 条件成立,则重复执行,直到条件不成立为止。
* 一般情况下,需要多次重复执行的代码,都可以用循环的方式来完成
* 循环不是必须要使用的,但是为了提高代码的重复使用率,所以有经验的开发者都会采用循环


##### 2.8 while循环


1. while循环的格式



while 条件:
    条件满足时,做的事情1
    条件满足时,做的事情2
    条件满足时,做的事情3
    ...(省略)...

2. 练习题:循环打印5次



i = 0
while i < 5:
    print("当前是第%d次执行循环" % (i + 1))
    print("i=%d" % i)
    i+=1

3. 结果:



当前是第1次执行循环
i=0
当前是第2次执行循环
i=1
当前是第3次执行循环
i=2
当前是第4次执行循环
i=3
当前是第5次执行循环
i=4

4. 死循环


由于程序员的原因,忘记 在循环内部 修改循环的判断条件,导致循环持续执⾏,程序⽆法终⽌!


##### 2.9 while循环应用


1. 计算1~100的累积和(包含1和100)


参考代码如下:



#encoding=utf-8

i = 1
sum = 0
while i <= 100:
sum = sum + i
i += 1

print(“1~100的累积和为:%d” % sum)


2. 计算1~100之间偶数的累积和(包含1和100)


参考代码如下:



#encoding=utf-8

i = 1
sum = 0
while i <= 100:
if i % 2 == 0:
sum = sum + i
i+=1

print(“1~100的累积和为:%d” % sum)


while循环嵌套


* 类似if的嵌套,while嵌套就是:while里面还有while


1. while嵌套的格式



while 条件1:

    条件1满足时,做的事情1
    条件1满足时,做的事情2
    条件1满足时,做的事情3
    ...(省略)...

    while 条件2:
        条件2满足时,做的事情1
        条件2满足时,做的事情2
        条件2满足时,做的事情3
        ...(省略)...

2. while嵌套应用


要求:打印如下图形:









参考代码:



i = 1
while i <= 5:
j = 1
while j <= 5:
print(“*”, end=" ")
j += 1
print()

i += 1

3.练习题:打印三角形


要求:打印如下图形:







参考代码:



i = 1
while i <= 5:
j = 1
while j <= i:
print(“*”, end=" ")
j += 1
print()

i += 1

4. 练习题: 猜拳游戏(while版)


使用while循环语句实现猜拳游戏.


2.10 for循环


for循环


像while循环一样,for可以完成循环的功能。


在Python中 for循环可以遍历任何序列的项目,如一个列表或者一个字符串等。


for循环的格式



for 临时变量 in 列表或者字符串等可迭代对象:
循环满足条件时执行的代码


demo1



name = ‘harry’

for x in name:
print(x)


运行结果如下:



h
a
r
r
y


demo2



for x in name:
print(x)
if x == ‘l’:
print(“Hello world!”)


运行结果如下:



h
e
l
Hello world!
l
Hello world!
o


demo3



range(5) 在python就业班中进行讲解会牵扯到迭代器的知识,

作为刚开始学习python的我们,此阶段仅仅知道range(5)表示可以循环5次即可

for i in range(5):
print(i)

‘’’
效果等同于 while 循环的:

i = 0
while i < 5:
print(i)
i += 1
‘’’


运行结果如下:



0
1
2
3
4


##### 2.10 break和continue


1. break


1.1 for循环


* 普通的循环示例如下:



name = ‘harry’

for x in name:
print(‘----’)
print(x)
else:
print(“for循环过程中,如果没有执行break退出,则执行本语句”)


运行结果:




h

a

r

r

y
for循环过程中,如果没有执行break退出,则执行本语句


* 带有break的循环示例如下:



name = ‘harry’

for x in name:
print(‘----’)
if x == ‘y’:
break
print(x)
else:
print(“for循环过程中,如果没有执行break退出,则执行本语句”)


运行结果:




h

a

r

r


##### 2.11 while循环


* 普通的循环示例如下:



i = 0

while i<5:
i = i+1
print(‘----’)
print(i)
else:
print(“while循环过程中,如果没有执行break退出,则执行本语句”)


运行结果:




1

2

3

4

5
while循环过程中,如果没有break则执行


* 带有break的循环示例如下:



i = 0

while i<5:
i = i+1
print(‘----’)
if i==3:
break
print(i)
else:
print(“while循环过程中,如果没有执行break退出,则执行本语句”)


运行结果:




1

2


##### **总结:**


* break的作用:立刻结束break所在的循环


2. continue


2.1. for循环


* 带有continue的循环示例如下:



name = ‘harry’

for x in name:
print(‘----’)
if x == ‘a’:
continue
print(x)
else:
print(“while循环过程中,如果没有break则执行”)


运行结果:




h


r

r

y
while循环过程中,如果没有break则执行


2.2 while循环


* 带有continue的循环示例如下:



i = 0

while i<5:
i = i+1
print(‘----’)
if i==3:
continue
print(i)


运行结果:




1

2


4

5


小结:


* continue的作用:用来结束本次循环,紧接着执行下一次的循环


3. 注意点


* break/continue只能用在循环中,除此以外不能单独使用
* break/continue在嵌套循环中,只对最近的一层循环起作用


#### 3.容器类型


字符串,列表,元组,字典,集合


##### 3.1字符串介绍


字符串介绍


1. python中字符串的格式


如下定义的变量a,存储的是数字类型的值



a = 100

如下定义的变量b,存储的是字符串类型的值



b = "hello"
或者
b = 'hello'
或者
b = '''hello'''
或者
b = """hello"""

小总结:


* 单引号或者双引号或者三引号中的数据,就是字符串


##### 3.2 字符串输出输入


3.2.1 字符串输出


1.格式化操作符



name = ‘harry’
position = ‘python工程师’
address = ‘北京市’

print(‘--------------------------------------------------’)
print(“姓名:%s” % name)
print(“职位:%s” % position)
print(“公司地址:%s” % address)
print(‘--------------------------------------------------’)


结果:




姓名:harry
职位:python工程师
公司地址:上海市


2.f-strings


f-strings 提供一种简洁易读的方式, 可以在字符串中包含 Python 表达式. f-strings 以字母 ‘f’ 或 ‘F’ 为前缀, 格式化字符串使用一对单引号、双引号、三单引号、三双引号. 格式化字符串中



name = ‘Harry’
age = 18
format_string1 = f’我的名字是 {name}, 我的年龄是 {age}’
format_string2 = f"我的名字是 {name}, 我的年龄是 {age}"
format_string3 = F’‘‘我的名字是 {name}, 我的年龄是 {age}’’’
format_string4 = F"““我的名字是 {name}, 我的年龄是 {age}””"
format_string5 = f’3 + 5 = {3 + 5}’
a = 10
b = 20
format_string6 = f’3 + 5 = {a + b}’

两个花括号会被替换为一个花括号, 注意{{}} 不表示表达式

format_string7 = F’我的名字是 {{name}}, 我的年龄是 {{age}}’

print(format_string1)
print(format_string2)
print(format_string3)
print(format_string4)
print(format_string5)
print(format_string6)
print(format_string7)


结果:



我的名字是 Harry, 我的年龄是 18
我的名字是 Harry, 我的年龄是 18
我的名字是 Harry, 我的年龄是 18
我的名字是 Harry, 我的年龄是 18
3 + 5 = 8
3 + 5 = 30
我的名字是 {name}, 我的年龄是 {age}


3.2.2 字符串输入


python 在input的时候,通过它能够完成从键盘获取数据,然后保存到指定的变量中;


注意:input获取的数据,都以字符串的方式进行保存,即使输入的是数字,那么也是以字符串方式保存


demo:



userName = input(‘请输入用户名:’)
print(“用户名为:%s” % userName)

password = input(‘请输入密码:’)
print(“密码为:%s” % password)


结果:(根据输入的不同结果也不同)



请输入用户名:Harry
用户名为:Harry
请输入密码:123456
密码为:123456


##### 3.3 下标和切片


1. 下标索引


所谓`“下标”`,就是编号,就好比超市中的存储柜的编号,通过这个编号就能找到相应的存储空间


* 字符串中"下标"的使用

 列表与元组支持下标索引好理解,字符串实际上就是字符的数组,所以也支持下标索引。

 如果有字符串:`name = 'abcdef'`,在内存中的实际存储如下:

 如果想取出部分字符,那么可以通过`下标`的方法,(注意python中下标从 0 开始)

 

name = ‘abcdef’
print(name[0])
print(name[1])
print(name[2])

 运行结果:

 

a
b
c



2. 切片


切片是指对操作的对象截取其中一部分的操作。**字符串、列表、元组**都支持切片操作。


切片的语法:[起始:结束:步长]


注意:选取的区间从"起始"位开始,到"结束"位的前一位结束(不包含结束位本身),步长表示选取间隔。


我们以字符串为例讲解。


如果取出一部分,则可以在中括号[]中,使用:



 name = 'abcdef'

 print(name[0:3]) # 取 下标0~2 的字符

运行结果:


abc



 name = 'abcdef'

 print(name[0:5]) # 取 下标为0~4 的字符

运行结果:


abcde



 name = 'abcdef'

 print(name[3:5]) # 取 下标为3、4 的字符

运行结果:


de



 name = 'abcdef'

 print(name[2:]) # 取 下标为2开始到最后的字符

运行结果:
cdef



 name = 'abcdef'

 print(name[1:-1]) # 取 下标为1开始 到 最后第2个  之间的字符
    
      运行结果:
    ---------------------------------
    ebcd


a = “abcdef”
print(a[:3]) # ‘abc’

print(a[::2]) # ‘ace’

print(a[5:1:2]) # # ‘’

print(a[1:5:2]) # ‘bd’

print(a[::-2]) # ‘fdb’

print(a[5:1:-2]) # ‘fd’


给定一个字符串aStr, 请反转字符串



索引是通过下标取某一个元素

切片是通过下标去某一段元素

s = ‘Hello World!’

print(s[4])

print(s)

print(s[:]) # 取出所有元素(没有起始位和结束位之分),默认步长为1

print(s[1:]) # 从下标为1开始,取出 后面所有的元素(没有结束位)

print(s[:5]) # 从起始位置开始,取到 下标为5的前一个元素(不包括结束位本身)

print(s[:-1]) # 从起始位置开始,取到 倒数第一个元素(不包括结束位本身)

print(s[-4:-1]) # 从倒数第4个元素开始,取到 倒数第1个元素(不包括结束位本身)

print(s[1:5:2]) # 从下标为1开始,取到下标为5的前一个元素,步长为2(不包括结束位本身)

python 字符串快速逆置

print(s[::-1]) # 从后向前,按步长为1进行取值


##### 3.4 字符串常见操作


如有字符串info = ‘abca’,以下是常见的操作


1. find


find() 方法检测字符串中是否包含子字符串 str ,如果指定 beg(开始) 和 end(结束) 范围,则检查是否包含在指定范围内,如果指定范围内如果包含指定索引值,返回的是索引值在字符串中的起始位置。如果不包含索引值,返回-1。



info = ‘abca’
print(info.find(‘a’)) # 从下标0开始,查找在字符串里第一个出现的子串,返回结果:0

print(info.find(‘a’, 1)) # 从下标1开始,查找在字符串里第一个出现的子串:返回结果3

print(info.find(‘3’)) # 查找不到返回-1


2. index


Python index() 方法检测字符串中是否包含子字符串 str ,如果指定 beg(开始) 和 end(结束) 范围,则检查是否包含在指定范围内,该方法与 python find()方法一样,只不过如果str不在 string中会报一个异常。



info = ‘abca’
print(info.index(‘a’))
print(info.index(‘a’, 1))

print(info.index(3))

Traceback (most recent call last):
File “D:/guiderobot_python/pathfinder/apps/offline_master/init.py”, line 4, in
print(info.index(3))
TypeError: must be str, not int
0
3


3. count


返回 str在start和end之间 在 mystr里面出现的次数



mystr.count(str, start=0, end=len(mystr))



info = ‘abca’
print(info.count(‘a’))
print(info.count(‘a’, 1))
print(info.count(‘b’))

2
1
1


4. replace


把 mystr 中的 str1 替换成 str2,如果 count 指定,则替换不超过 count 次.



mystr.replace(str1, str2, mystr.count(str1))


5. split


以 str 为分隔符切片 mystr,如果 maxsplit有指定值,则仅分隔 maxsplit 个子字符串



mystr.split(str=" ", 2)


6. capitalize


把字符串的第一个字符大写



mystr.capitalize()


7. title


把字符串的每个单词首字母大写



a = “hello itcast”
a.title()
‘Hello Itcast’


8. startswith


检查字符串是否是以 hello 开头, 是则返回 True,否则返回 False



mystr.startswith(hello)


9. endswith


检查字符串是否以obj结束,如果是返回True,否则返回 False.



mystr.endswith(obj)


10. lower


转换 mystr 中所有大写字符为小写



mystr.lower()


11. upper


转换 mystr 中的小写字母为大写



mystr.upper()


12. lstrip


删除 mystr 左边的空白字符



mystr.lstrip()


13. rstrip


删除 mystr 字符串末尾的空白字符



mystr.rstrip()


14. strip


删除mystr字符串两端的空白字符



a = “\n\t itcast \t\n”
a.strip()
‘itcast’


15. rfind


类似于 find()函数,不过是从右边开始查找.



mystr.rfind(str, start=0,end=len(mystr) )


16. rindex


类似于 index(),不过是从右边开始.



mystr.rindex( str, start=0,end=len(mystr))


17. partition


把mystr以str分割成三部分,str前,str和str后



mystr.partition(str)


18. rpartition


类似于 partition()函数,不过是从右边开始.



mystr.rpartition(str)


19. splitlines


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



mystr.splitlines()


20. isalpha


如果 mystr 所有字符都是字母 则返回 True,否则返回 False



mystr.isalpha()


21. isdigit


如果 mystr 只包含数字则返回 True 否则返回 False.



mystr.isdigit()


22. isalnum


如果 mystr 所有字符都是字母或数字则返回 True,否则返回 False



mystr.isalnum()


23. isspace


如果 mystr 中只包含空格,则返回 True,否则返回 False.



mystr.isspace()


24. join


str 中每个元素后面拼接上mystr,构造出一个新的字符串



mystr.join(str)


##### 3.5 列表介绍


1. 列表的格式


变量A的类型为列表



namesList = ['xiaoWang','xiaoZhang','xiaoHua']

比C语言的数组强大的地方在于列表中的元素可以是不同类型的



testList = [1, 'a']

2. 打印列表


demo:



namesList = ['xiaoWang','xiaoZhang','xiaoHua']
print(namesList[0])
print(namesList[1])
print(namesList[2])

结果:



xiaoWang
xiaoZhang
xiaoHua

##### 3.6 列表循环遍历


列表的循环遍历


1. 使用for循环


为了更有效率的输出列表的每个数据,可以使用循环来完成


demo:



namesList = ['xiaoWang','xiaoZhang','xiaoHua']
for name in namesList:
    print(name)

结果:



xiaoWang
xiaoZhang
xiaoHua

2. 使用while循环


为了更有效率的输出列表的每个数据,可以使用循环来完成


demo:



namesList = ['xiaoWang','xiaoZhang','xiaoHua']

length = len(namesList)

i = 0

while i<length:
    print(namesList[i])
    i+=1

结果:



xiaoWang
xiaoZhang
xiaoHua

##### 3.7 列表相关操作


列表的相关操作


列表中存放的数据是可以进行修改的,比如"增"、“删”、“改”、“查”


1. 添加元素("增"append, extend, insert)


append


通过append可以向列表添加元素


demo:



定义变量A,默认有3个元素

A = [‘1’, ‘2’, ‘3’]

print(“-----添加之前,列表A的数据-----”)
for tempName in A:
print(tempName)

提示、并添加元素

temp = input(‘请输入要添加的学生姓名:’)
A.append(temp)

print(“-----添加之后,列表A的数据-----”)
for tempName in A:
print(tempName)


结果:



-----添加之前,列表A的数据-----
1
2
3
请输入要添加的学生姓名:4
-----添加之后,列表A的数据-----
1
2
3
4

Process finished with exit code 0


extend


通过extend可以将另一个集合中的元素逐一添加到列表中



a = [1, 2]
b = [3, 4]
a.append(b) # [1, 2, [3, 4]]
print(a)

a.extend(b)
print(a) # [1, 2, [3, 4], 3, 4]


insert


insert(index, object) 在指定位置index前插入元素object



a = [0, 1, 2]

a.insert(4, 9) # 在地4位插入数字9

print(a) # [0, 1, 2, 9]


2. 修改元素(“改”)


修改元素的时候,要通过下标来确定要修改的是哪个元素,然后才能进行修改


demo:



#定义变量A,默认有3个元素
A = ['xiaoWang','xiaoZhang','xiaoHua']

print("-----修改之前,列表A的数据-----")
for tempName in A:
    print(tempName)

#修改元素
A[1] = 'xiaoLu'

print("-----修改之后,列表A的数据-----")
for tempName in A:
    print(tempName)

结果:



-----修改之前,列表A的数据-----
xiaoWang
xiaoZhang
xiaoHua
-----修改之后,列表A的数据-----
xiaoWang
xiaoLu
xiaoHua

3. 查找元素("查"in, not in, index, count)


所谓的查找,就是看看指定的元素是否存在


in, not in


python中查找的常用方法为:


* in(存在),如果存在那么结果为true,否则为false
* not in(不存在),如果不存在那么结果为true,否则false


demo



#待查找的列表
nameList = ['xiaoWang','xiaoZhang','xiaoHua']

#获取用户要查找的名字
findName = input('请输入要查找的姓名:')

#查找是否存在
if findName in nameList:
    print('在字典中找到了相同的名字')
else:
    print('没有找到')

结果1:(找到)


结果2:(没有找到)


说明:



> 
> in的方法只要会用了,那么not in也是同样的用法,只不过not in判断的是不存在
> 
> 
> 


index, count


index和count与字符串中的用法相同



a = [‘a’, ‘b’, ‘c’, ‘a’, ‘b’]
a.index(‘a’, 1, 3) # 注意是左闭右开区间
Traceback (most recent call last):
File “”, line 1, in
ValueError: ‘a’ is not in list
a.index(‘a’, 1, 4) # 3
a.count(‘b’) # 2
a.count(‘d’) # 0


4.删除元素(del, pop, remove)


类比现实生活中,如果某位同学调班了,那么就应该把这个条走后的学生的姓名删除掉;在开发中经常会用到删除这种功能。


列表元素的常用删除方法有:


* del:根据下标进行删除
* pop:删除最后一个元素
* remove:根据元素的值进行删除


demo:(del)



movieName = ['加勒比海盗','骇客帝国','第一滴血','指环王','霍比特人','速度与激情']

print('------删除之前------')
for tempName in movieName:
    print(tempName)

del movieName[2]

print('------删除之后------')
for tempName in movieName:
    print(tempName)

结果:



------删除之前------
加勒比海盗
骇客帝国
第一滴血
指环王
霍比特人
速度与激情
------删除之后------
加勒比海盗
骇客帝国
指环王
霍比特人
速度与激情

demo:(pop)



movieName = ['加勒比海盗','骇客帝国','第一滴血','指环王','霍比特人','速度与激情']

print('------删除之前------')
for tempName in movieName:
    print(tempName)

movieName.pop()

print('------删除之后------')
for tempName in movieName:
    print(tempName)

结果:



------删除之前------
加勒比海盗
骇客帝国
第一滴血
指环王
霍比特人
速度与激情
------删除之后------
加勒比海盗
骇客帝国
第一滴血
指环王
霍比特人

demo:(remove)



movieName = ['加勒比海盗','骇客帝国','第一滴血','指环王','霍比特人','速度与激情']

print('------删除之前------')
for tempName in movieName:
    print(tempName)

movieName.remove('指环王')

print('------删除之后------')
for tempName in movieName:
    print(tempName)

结果:



------删除之前------
加勒比海盗
骇客帝国
第一滴血
指环王
霍比特人
速度与激情
------删除之后------
加勒比海盗
骇客帝国
第一滴血
霍比特人
速度与激情

5. 排序(sort, reverse)


sort方法是将list按特定顺序重新排列,默认为由小到大,参数reverse=True可改为倒序,由大到小。


reverse方法是将list逆置。



a = [1, 4, 2, 3]
a.reverse()
print(a) # [3, 2, 4, 1]
a.sort()
print(a) # [1, 2, 3, 4]
a.sort(reverse=True)
print(a) # [4, 3, 2, 1]


##### 3.8 列表嵌套


1. 列表嵌套


类似while循环的嵌套,列表也是支持嵌套的


一个列表中的元素又是一个列表,那么这就是列表的嵌套



schoolNames = [
[‘北京大学’, ‘清华大学’],
[‘南开大学’, ‘天津大学’, ‘天津师范大学’],
[‘山东大学’, ‘中国海洋大学’]
]


2. 应用


一个学校,有3个办公室,现在有8位老师等待工位的分配,请编写程序,完成随机的分配



#encoding=utf-8

import random

定义一个列表用来保存3个办公室

offices = [[],[],[]]

定义一个列表用来存储8位老师的名字

names = [‘A’,‘B’,‘C’,‘D’,‘E’,‘F’,‘G’,‘H’]

i = 0
for name in names:
index = random.randint(0,2)
offices[index].append(name)

i = 1
for tempNames in offices:
print(‘办公室%d的人数为:%d’%(i,len(tempNames)))
i+=1
for name in tempNames:
print(“%s”%name,end=‘’)
print(“\n”)
print(“-”*20)


运行结果如下:



办公室1的人数为:5
ABDEH


办公室2的人数为:1
F


办公室3的人数为:2
CG


Process finished with exit code 0


##### 3.9 元组


Python的元组与列表类似,不同之处在于**元组的元素不能修改**。元组使用小括号,列表使用方括号。



aTuple = (‘et’, 77, 99.9)
print(aTuple) # (‘et’, 77, 99.9)


说明: **python中不允许修改元组的数据,包括不能删除其中的元素。**


count, index


index和count与字符串和列表中的用法相同



a = (‘a’, ‘b’, ‘c’, ‘a’, ‘b’)
a.index(‘a’, 1, 3) # 注意是左闭右开区间
Traceback (most recent call last):
File “”, line 1, in
ValueError: tuple.index(x): x not in tuple
a.index(‘a’, 1, 4) # 3
a.count(‘b’) # 2
a.count(‘d’) # 0


1.对于容器型数据类型list,无论谁都可以对其增删改查,那么有一些重要的数据放在list中是不安全的,所以需要一种容器类的数据类型存放重要的数据,创建之初只能查看而不能增删改,这种数据类型就是元祖。


元祖:俗称不可变的列表,又被成为只读列表,元祖也是python的基本数据类型之一,


用小括号括起来,里面可以放任何数据类型的数据,查询可以,循环也可以,切片也可以.但就是不能改.在python中关键字是tuple



tu = (‘我’,‘怎么’,‘这么’,‘可爱’)

tu1 = tu[0] # 记性下标
print(tu1)

for i in tu:
print(i) # 进行for循环

tu2 = tu[0:3]
print(tu2) # 进行切片

结果:
Traceback (most recent call last):
File “D:/python_object/path2/test.py”, line 1286, in
tu[0] = ‘你’
NameError: name ‘tu’ is not defined


关于不可变, 注意: 这里元组的不可变的意思是子元素不可变. 而子元素内部的子元素是可以变, 这取决于子元素是否是可变对象.


元组中如果只有一个元素. 一定要添加一个逗号, 否则就不是元组



tup = (“harry”)
print(type(tup)) # type是查看数据类型

结果: # class:str

tu = (‘harry’,)
print(type(tu)) #type是查看数据类型

结果: class:tuple


这个知识点如何使用


1.可遍历


2.可切片


3.有len,count,index方法


2.1 元祖嵌套



tu = (‘今天姐姐不在家’,‘姐夫和小姨子在客厅聊天’,(‘姐夫问小姨子税后多少钱’,‘小姨子低声说道说和姐夫还提钱’))
tu1 = tu[0]
tu2 = tu[1]
tu3 = tu[2][0]
tu4 = tu[2][1]

print(tu1)
print(tu2)
print(tu3)
print(tu4)
结果:
今天姐姐不在家
姐夫和小姨子在客厅聊天
姐夫问小姨子税后多少钱
小姨子低声说道说和姐夫还提钱


在哪里使用


就是将一些非常重要的不可让人改动的数据放在元祖中,只供查看。写项目的时候会有配置文件,配置文件中的不想让人修改的单个变量使用常量,如果是多个不想让人修改的就是用元组来存储


二.range


翻译过来就是范围,那我们我来先看下.



range(0,5,1)

参数第一个是范围的起始位置
参数第二个是范围的结束位置
参数第三个是步长
print(range(0,5))

结果:

range(0, 5) #一个范围

我们可以通过list方法来转换这个范围来查看一下

l = list(range(0,5))
print(l)

结果:

[0, 1, 2, 3, 4]
l = list(range(0,5,2))
print(l)

结果:

[0, 2, 4] # 这个结果就会发现和我之前用步长获取的内容是相似的,是的他就是步长


##### 3.10 字典


字典的介绍


想一想:



> 
> 如果有列表
> 
> 
> 



nameList = [‘xiaoZhang’, ‘xiaoWang’, ‘xiaoLi’];



> 
> 需要对"xiaoWang"这个名字写错了,通过代码修改:
> 
> 
> 



nameList[1] = ‘xiaoxiaoWang’



> 
> 如果列表的顺序发生了变化,如下
> 
> 
> 



nameList = [‘xiaoWang’, ‘xiaoZhang’, ‘xiaoLi’];



> 
> 此时就需要修改下标,才能完成名字的修改
> 
> 
> 



nameList[0] = ‘xiaoxiaoWang’



> 
> ###### **`有没有方法,既能存储多个数据,还能在访问元素的很方便就能够定位到需要的那个元素呢?`**
> 
> 
> 


答:



> 
> 字典
> 
> 
> 


另一个场景:


学生信息列表,每个学生信息包括学号、姓名、年龄等,如何从中找到某个学生的信息?



studens = [[1001, “王bao强”, 24], [1002, “马rong”, 23], [1005, “宋x”,24], …]


2. 软件开发中的字典


变量info为字典类型:



info = {‘name’:‘班长’, ‘id’:100, ‘sex’:‘f’, ‘address’:‘地球亚洲中国北京’}


说明:


* 字典和列表一样,也能够存储多个数据
* 列表中找某个元素时,是根据下标进行的
* 字典中找某个元素时,是根据’名字’(就是冒号:前面的那个值,例如上面代码中的’name’、‘id’、‘sex’)
* 字典的每个元素由2部分组成,键:值。例如 ‘name’:‘班长’ ,'name’为键,'班长’为值


3. 根据键访问值



info = {‘name’:‘班长’, ‘id’:100, ‘sex’:‘f’, ‘address’:‘地球亚洲中国北京’}

print(info[‘name’])
print(info[‘address’])


结果:



班长
地球亚洲中国北京


若访问不存在的键,则会报错:



info[‘age’]
Traceback (most recent call last):
File “”, line 1, in
KeyError: ‘age’


在我们不确定字典中是否存在某个键而又想获取其值时,可以使用get方法,还可以设置默认值:



age = info.get(‘age’)
age #'age’键不存在,所以age为None
type(age)
<type ‘NoneType’>
age = info.get(‘age’, 18) # 若info中不存在’age’这个键,就返回默认值18
age
18


##### 3.11 字典常见操作


字典的常见操作1


1. 查看元素


除了使用key查找数据,还可以使用get来获取数据


demo:



info = {'name':'吴彦祖','age':18}

print(info['age']) # 获取年龄

# print(info['sex']) # 获取不存在的key,会发生异常

print(info.get('sex')) # 获取不存在的key,获取到空的内容,不会出现异常

2. 修改元素


字典的每个元素中的数据是可以修改的,只要通过key找到,即可修改


demo:



info = {'name':'班长', 'id':100, 'sex':'f', 'address':'地球亚洲中国北京'}

newId = input('请输入新的学号')

info['id'] = int(newId)

print('修改之后的id为%d:'%info['id'])

结果:



请输入新的学号1
修改之后的id为1:


3. 添加元素


demo:访问不存在的元素



info = {'name':'班长', 'sex':'f', 'address':'地球亚洲中国北京'}

print('id为:%d'%info['id'])

如果在使用 **变量名[‘键’] = 数据** 时,这个“键”在字典中,不存在,那么就会新增这个元素


demo:添加新的元素



info = {'name':'班长', 'sex':'f', 'address':'地球亚洲中国北京'}

# print('id为:%d'%info['id'])#程序会终端运行,因为访问了不存在的键

newId = input('请输入新的学号')

info['id'] = newId

print('添加之后的id为:%d'%info['id'])

结果:



请输入新的学号188
添加之后的id为: 188

4. 删除元素


对字典进行删除操作,有一下几种:


* del
* clear()


demo:del删除指定的元素



info = {'name':'班长', 'sex':'f', 'address':'地球亚洲中国北京'}

print('删除前,%s'%info['name'])

del info['name']

print('删除后,%s'%info['name'])

demo:del删除整个字典



info = {'name':'monitor', 'sex':'f', 'address':'China'}

print('删除前,%s'%info)

del info

print('删除后,%s'%info)

demo:clear清空整个字典



info = {'name':'monitor', 'sex':'f', 'address':'China'}

print('清空前,%s'%info)

info.clear()

print('清空后,%s'%info)

字典的常见操作2


1. len()


测量字典中,键值对的个数


2. keys


返回一个包含字典所有KEY的列表


3. values


返回一个包含字典所有value的列表


4. items


返回一个包含所有(键,值)元祖的列表


##### 3.12 字典遍历


遍历


通过for … in … 我们可以遍历字符串、列表、元组、字典等


**注意python语法的缩进**


1. 字符串遍历



a_str = “hello itcast”
for char in a_str:
… print(char,end=’ ')

h e l l o i t c a s t


2. 列表遍历



a_list = [1, 2, 3, 4, 5]
for num in a_list:
… print(num,end=’ ')

1 2 3 4 5


3. 元组遍历



a_turple = (1, 2, 3, 4, 5)
for num in a_turple:
… print(num,end=" ")
1 2 3 4 5


4. 字典遍历


4.1. 遍历字典的key(键)


4.2. 遍历字典的value(值)


4.3. 遍历字典的项(元素)


4.4. 遍历字典的key-value(键值对)


实现带下标索引的遍历



chars = [‘a’, ‘b’, ‘c’, ‘d’]
i = 0
for chr in chars:
… print(“%d %s”%(i, chr))
… i += 1

0 a
1 b
2 c
3 d


6. enumerate()



> 
> enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
> 
> 
> 



chars = [‘a’, ‘b’, ‘c’, ‘d’]
for i, chr in enumerate(chars):
… print i, chr

0 a
1 b
2 c
3 d


##### 3.13 有序字典


有序字典:OrderDict


我们先看一段代码, 此代码运行在 Python3.5 版本中:



创建无序字典

my_dict = dict()

向字典中添加元素

my_dict[‘one’] = 1
my_dict[‘two’] = 2
my_dict[‘three’] = 3
my_dict[‘four’] = 4
print(my_dict)


输出结果(不固定):



{‘three’: 3, ‘two’: 2, ‘four’: 4, ‘one’: 1}


输出结果并不是按照我们创建字典、添加元素的顺序输出, 这是由于 dict 是无序的. 如果我们想最终打印输出的顺序和我们操作时的顺序保持一致, 我们就需要使用有序字典:



from collections import OrderedDict

创建有序字典

my_dict = OrderedDict()

向字典中添加元素

my_dict[‘one’] = 1
my_dict[‘two’] = 2
my_dict[‘three’] = 3
my_dict[‘four’] = 4
print(my_dict)


输出结果:



OrderedDict([(‘one’, 1), (‘two’, 2), (‘three’, 3), (‘four’, 4)])


在 Python3.6 版本中, dict 字典已经经过优化, 变为有序字典. 并且字典所占用的内存占用减少了20%到25%.


第一段代码在 Python3.6 运行下, 输出结果如下:



{‘one’: 1, ‘two’: 2, ‘three’: 3, ‘four’: 4}


##### 3.14 公共方法


1. 运算符




| 运算符 | Python 表达式 | 结果 | 描述 | 支持的数据类型 |
| --- | --- | --- | --- | --- |
| + | [1, 2] + [3, 4] | [1, 2, 3, 4] | 合并 | 字符串、列表、元组 |
| \* | [‘Hi!’] \* 4 | [‘Hi!’, ‘Hi!’, ‘Hi!’, ‘Hi!’] | 复制 | 字符串、列表、元组 |
| in | 3 in (1, 2, 3) | True | 元素是否存在 | 字符串、列表、元组、字典 |
| not in | 4 not in (1, 2, 3) | True | 元素是否不存在 | 字符串、列表、元组、字典 |



"hello " + “itcast”
‘hello itcast’
[1, 2] + [3, 4]
[1, 2, 3, 4]
(‘a’, ‘b’) + (‘c’, ‘d’)
(‘a’, ‘b’, ‘c’, ‘d’)



‘ab’ * 4
‘ababab’
[1, 2] * 4
[1, 2, 1, 2, 1, 2, 1, 2]
(‘a’, ‘b’) * 4
(‘a’, ‘b’, ‘a’, ‘b’, ‘a’, ‘b’, ‘a’, ‘b’)


in



‘itc’ in ‘hello itcast’
True
3 in [1, 2]
False
4 in (1, 2, 3, 4)
True
“name” in {“name”:“Delron”, “age”:24}
True


**注意,in在对字典操作时,判断的是字典的键**


2. python内置函数


Python包含了以下内置函数




| 序号 | 函数 | 描述 |
| --- | --- | --- |
| 1 | len(item) | 计算容器中元素个数 |
| 2 | max(item) | 返回容器中元素最大值 |
| 3 | min(item) | 返回容器中元素最小值 |
| 4 | del(item) | 删除变量 |


len



len(“hello itcast”)
12
len([1, 2, 3, 4])
4
len((3,4))
2
len({“a”:1, “b”:2})
2


**注意:len在操作字典数据时,返回的是键值对个数。**


max



max(“hello itcast”)
‘t’
max([1,4,522,3,4])
522
max({“a”:1, “b”:2})
‘b’
max({“a”:10, “b”:2})
‘b’
max({“c”:10, “b”:2})
‘c’


del


del有两种用法,一种是del加空格,另一种是del()



a = 1
a
1
del a
a
Traceback (most recent call last):
File “”, line 1, in
NameError: name ‘a’ is not defined
a = [‘a’, ‘b’]
del a[0]
a
[‘b’]
del(a)
a
Traceback (most recent call last):
File “”, line 1, in
NameError: name ‘a’ is not defined


3. 多维列表/元祖访问的示例



tuple1 = [(2,3),(4,5)]
tuple1[0]
(2, 3)
tuple1[0][0]
2
tuple1[0][2]
Traceback (most recent call last):
File “”, line 1, in
IndexError: tuple index out of range

tuple1[0][1]
3
tuple1[2][2]
Traceback (most recent call last):
File “”, line 1, in
IndexError: list index out of range

tuple2 = tuple1+[(3)]
tuple2
[(2, 3), (4, 5), 3]
tuple2[2]
3
tuple2[2][0]
Traceback (most recent call last):
File “”, line 1, in
TypeError: ‘int’ object is not subscriptable


#### 4. 函数


##### 4.1. 函数介绍


函数就是一个具有独立功能的代码块,可以提高代码的复用性



1、什么是函数
函数就相当于具备某一功能的工具
函数的使用必须遵循一个原则:
先定义
后调用
2、为何要用函数
1、组织结构不清晰,可读性差
2、代码冗余
3、可维护性、扩展性差

3、如何用函数
先定义
三种定义方式
后调用
三种调用方式

    返回值
        三种返回值的形式

python中,采用下面的语法定义函数:



def 函数名(参数):
# 内部代码
return 表达式


例如:



def summer(lis):
“”"
这里是函数的说明文档,doc的位置
:param lis: 参数列表的说明
:return: 返回值的说明
“”"
total = 0
for i in lis:
total += i
return total


二,函数定义语法介绍



一、先定义

定义的语法

‘’’
def 函数名(参数1,参数2,…):
“”“文档描述”“”
函数体
return 值
‘’’


注意:


在定义函数的过程中



  1. 函数代码块以def关键词开头,一个空格之后接函数标识符名称和圆括号(),再接个冒号。

2.任何传入的参数必须放在圆括号中间。

3.函数的第一行语句后可以选择性地使用文档字符串—用于存放函数说明。

4.函数内容以冒号起始,并且缩进。

5.使用return结束函数。默认返回None。

6.return语句依然在函数体内部,不能回退缩进。直到函数的所有代码写完,才回退缩进,表示函数体结束。


return语句:


一旦函数执行过程遇到return语句,那么之后函数体内的所有代码都会被忽略,直接跳出函数体。



def func():
pass
return
# 此时,后面的代码其实是永远无法执行的。
# 但从语法和词法层面,这些没有错误。
print(1)
abs(-1)
pass


三,函数的定义与调用



无参函数

示范1
def bar(): # bar=函数的内存地址
print(‘from bar’)

def foo():
# print(bar)
bar()
print(‘from foo’)

foo()

示范2
def foo():
# print(bar)
bar()
print(‘from foo’)

def bar(): # bar=函数的内存地址
print(‘from bar’)

foo()

示范3
def foo():
# print(bar)
bar()
print(‘from foo’)

foo()

def bar(): # bar=函数的内存地址
print(‘from bar’)

形式二:有参函数
def func(x,y): # x=1 y=2
print(x,y)
func(1,2)

形式三:空函数,函数体代码为pass
def func(x, y):
pass


四,定义函数的三种形式



三种定义方式各用在何处
1、无参函数的应用场景
def interactive():
name=input('username>>: ')
age=input('age>>: ')
gender=input('gender>>: ')
msg=‘名字:{} 年龄:{} 性别’.format(name,age,gender)
print(msg)

interactive()
interactive()
interactive()
interactive()

2、有参函数的应用场景
def add(x,y): # 参数-》原材料
# x=20
# y=30
res=x + y
# print(res)
return res # 返回值-》产品

add(10,2)

res=add(20,30)
print(res)

3、空函数的应用场景
def auth_user():
“”“user authentication function”“”
pass

def download_file():
“”“download file function”“”
pass

def upload_file():
“”“upload file function”“”
pass

def ls():
“”“list contents function”“”
pass

def cd():
“”“change directory”“”
pass

二、调用函数
1、语句的形式:只加括号调用函数
interactive()
add(1,2)

2、表达式形式:
def add(x,y): # 参数-》原材料
res=x + y
return res # 返回值-》产品
赋值表达式
res=add(1,2)
print(res)
数学表达式
res=add(1,2)*10
print(res)

3、函数调用可以当做参数
res=add(add(1,2),10)
print(res)

三、函数返回值
return是函数结束的标志,即函数体代码一旦运行到return会立刻
终止函数的运行,并且会将return后的值当做本次运行的结果返回:
1、返回None:函数体内没有return
return
return None

2、返回一个值:return 值
def func():
return 10

res=func()
print(res)

3、返回多个值:用逗号分隔开多个值,会被return返回成元组
def func():
return 10, ‘aa’, [1, 2]

res = func()
print(res, type(res))


##### 4.2. 函数的定义和调用


注意:每次调用函数时,函数都会从头开始执行,当这个函数中的代码执行完毕后,意味着调用结束了


当然了如果函数中执行到了return也会结束函数


##### 4.3. 函数的文档说明



def test(a,b):
“”“用来完成对2个数求和”“”
print(“%d” % (a+b))
test(11,33)


##### 4.4. 函数的参数



def func():
a = 11
b = 12
c = a + b
print©
func()

a = 10
b = 12
def func():
c = a + b
print©
func()


调用函数时参数的顺序



def test(a,b):
print(a,b)

test(1,2)

test(b=1,a=3)

test()


小结:



定义时小括号中的参数,用来接收参数用的,称为 “形参”
调用时小括号中的参数,用来传递给函数用的,称为 “实参”


1. 缺省参数


调用函数时,缺省参数的值如果没有传入,则取默认值。


下例会打印默认的age,如果age没有被传入:



def printinfo(name, age=35):

打印任何传入的字符串

print(“name: %s” % name)
print(“age %d” % age)

调用printinfo函数

printinfo(name=“miki”) # 在函数执行过程中 age去默认值35
printinfo(age=9 ,name=“miki”)


以上实例输出结果:



name: miki
age: 35
name: miki
age: 9


总结:


* 在形参中默认有值的参数,称之为缺省参数
* 注意:带有默认值的参数一定要位于参数列表的最后面

 

def printinfo(name, age=35, sex):
… print name

File “”, line 1
SyntaxError: non-default argument follows default argument



2. 不定长参数


有时可能需要一个函数能处理比当初声明时更多的参数, 这些参数叫做不定长参数,声明时不会命名。


基本语法如下:



def functionname([formal_args,] *args, **kwargs):
“”“函数_文档字符串”“”
function_suite
return [expression]


注意:


* 加了星号(\*)的变量args会存放所有未命名的变量参数,args为元组
* 而加\*\*的变量kwargs会存放命名参数,即形如key=value的参数, kwargs为字典.



def fun(a, b, *args, **kwargs):
… “”“不定长参数演示示例”“”
… print(“a =%d” % a)
… print(“b =%d” % b)
… print(“args:”)
… print(args)
… print("kwargs: ")
… for key, value in kwargs.items():
… print(“key=%s” % value)

fun(1, 2, 3, 4, 5, m=6, n=7, p=8) # 注意传递的参数对应
a = 1
b = 2
args:
(3, 4, 5)
kwargs:
p = 8
m = 6
n = 7

c = (3, 4, 5)
d = {“m”:6, “n”:7, “p”:8}
fun(1, 2, *c, **d) # 注意元组与字典的传参方式
a = 1
b = 2
args:
(3, 4, 5)
kwargs:
p = 8
m = 6
n = 7

fun(1, 2, c, d) # 注意不加星号与上面的区别
a = 1
b = 2
args:
((3, 4, 5), {‘p’: 8, ‘m’: 6, ‘n’: 7})
kwargs:


3. 缺省参数在\*args后面



def sum_nums_3(a, *args, b=22, c=33, **kwargs):
print(a)
print(b)
print©
print(args)
print(kwargs)

sum_nums_3(100, 200, 300, 400, 500, 600, 700, b=1, c=2, mm=800, nn=900)


说明:


* 如果很多个值都是不定长参数,那么这种情况下,可以将缺省参数放到 \*args的后面, 但如果有\*\*kwargs的话,\*\*kwargs必须是最后的


##### 4.5. 函数的返回值



#定义函数
def add2num(a, b):
return a+b

#调用函数,顺便保存函数的返回值
result = add2num(100,98)

#因为result已经保存了add2num的返回值,所以接下来就可以使用了
print(result)


1. 多个return?



def create_nums():
print(“—1—”)
return 1 # 函数中下面的代码不会被执行,因为return除了能够将数据返回之外,还有一个隐藏的功能:结束函数
print(“—2—”)
return 2
print(“—3—”)


总结1:


* 一个函数中可以有多个return语句,但是只要有一个return语句被执行到,那么这个函数就会结束了,因此后面的return没有什么用处
* 如果程序设计为如下,是可以的因为不同的场景下执行不同的return

 

def create_nums(num):
print(“—1—”)
if num == 100:
print(“—2—”)
return num+1 # 函数中下面的代码不会被执行,因为return除了能够将数据返回之外,还有一个隐藏的功能:结束函数
else:
print(“—3—”)
return num+2
print(“—4—”)

result1 = create_nums(100)
print(result1) # 打印101
result2 = create_nums(200)
print(result2) # 打印202



2. 一个函数返回多个数据的方式



def calc_num(a, b):
num1 = a//b
num2 = a%b
return num1, num2 #默认是元组

result = calc_num(5, 2)
print(result) # 输出(2, 1)


总结2:


* return后面可以是元组,列表、字典等,只要是能够存储多个数据的类型,就可以一次性返回多个数据

 
  def function():
      # return [1, 2, 3]
      # return (1, 2, 3)
      return {"num1": 1, "num2": 2, "num3": 3}
* 如果return后面有多个数据,那么默认是元组

 
  In [1]: a = 1, 2
  In [2]: a
  Out[2]: (1, 2)

  In [3]:
  In [3]: b = (1, 2)
  In [4]: b
  Out[4]: (1, 2)

  In [5]:


##### 4.6. 函数的嵌套调用


一个函数里面又调用了另外一个函数,这就是所谓的函数嵌套调用



def testB():
print(‘---- testB start----’)
print(‘这里是testB函数执行的代码…(省略)…’)
print(‘---- testB end----’)

def testA():
print(‘---- testA start----’)
testB()
print(‘---- testA end----’)

testA()


* 如果函数A中,调用了另外一个函数B,那么先把函数B中的任务都执行完毕之后才会回到上次 函数A执行的位置


##### 4.7. 函数的应用


1. 写一个函数打印一条横线
2. 打印自定义行数的横线



打印一条横线

def printOneLine():
print(“-”*30)

printOneLine()

打印多条横线

def printNumLine(num):
i=0

# 因为printOneLine函数已经完成了打印横线的功能,
# 只需要多次调用此函数即可
while i < num:
    printOneLine()
    i += 1

printNumLine(30)


1. 写一个函数求三个数的和
2. 写一个函数求三个数的平均值



求3个数的和

def sum3Number(a,b,c):
return a+b+c # return 的后面可以是数值,也可是一个表达式

完成对3个数求平均值

def average3Number(a,b,c):

# 因为sum3Number函数已经完成了3个数的就和,所以只需调用即可
# 即把接收到的3个数,当做实参传递即可
sumResult = sum3Number(a,b,c)
aveResult = sumResult/3.0
return aveResult

调用函数,完成对3个数求平均值

result = average3Number(11,2,55)
print(“average is %d”%result)


##### 4.8. 局部变量



def test1():
a = 300
print(a)
a = 200
print(a)
def test2():
a = 500
print(a)
test1()
test2()


* 局部变量,就是在函数内部定义的变量
* 其作用范围是这个函数内部,即只能在这个函数中使用,在函数的外部是不能使用的
* 因为其作用范围只是在自己的函数内部,所以不同的函数可以定义相同名字的局部变量(打个比方,把你、我是当做成函数,把局部变量理解为每个人手里的手机,你可有个iPhone8,我当然也可以有个iPhone8了, 互不相关)
* 局部变量的作用,为了临时保存数据需要在函数中定义变量来进行存储
* 当函数调用时,局部变量被创建,当函数调用完成后这个变量就不能够使用了


##### 4.9. 全局变量



定义全局变量

a = 100

def test1():
print(a) # 虽然没有定义变量a但是依然可以获取其数据

def test2():
print(a) # 虽然没有定义变量a但是依然可以获取其数据

调用函数

test1()
test2()


* 在函数外边定义的变量叫做`全局变量`
* 全局变量能够在所有的函数中进行访问



a = 100
def test1():
a = 300
print(“,1”)
a = 200
print(“…2”)
def test2():
print(" …3")

调用函数

test1()
test2()


* 当函数内出现局部变量和全局变量相同名字时,函数内部中的 `变量名 = 数据` 此时理解为定义了一个局部变量,而不是修改全局变量的值
* 如果在函数中出现`global 全局变量的名字` 那么这个函数中即使出现和全局变量名相同的`变量名 = 数据` 也理解为对全局变量进行修改,而不是定义局部变量
* 如果在一个函数中需要对多个全局变量进行修改,那么可以使用



 # 可以使用一次global对多个全局变量进行声明
 global a, b
 # 还可以用多次global声明都是可以的
 # global a
 # global b

##### 4.10. 多个函数共享数据


多个函数函数之间共享数据


一般在实际开发过程中,一个程序往往由多个函数(后面知识中会讲解类)组成,并且多个函数共享某些数据,这种场景是经常出现的,因此下面来总结下,多个函数中共享数据的几种方式


1. 使用全局变量



g_num = 0

def test1():
global g_num
# 将处理结果存储到全局变量g_num中…
g_num = 100

def test2():
# 通过获取全局变量g_num的值, 从而获取test1函数处理之后的结果
print(g_num)

1. 先调用test1得到数据并且存到全局变量中

test1()

2. 再调用test2,处理test1函数执行之后的这个值

test2()


2. 使用函数的返回值



def test1():
# 通过return将一个数据结果返回
return 50

def test2(num):
# 通过形参的方式保存传递过来的数据,就可以处理了
print(num)

1. 先调用test1得到数据并且存到变量result中

result = test1()

2. 调用test2时,将result的值传递到test2中,从而让这个函数对其进行处理

test2(result)


##### 4.11. 拆包,交换两个变量的值


1.对容器类型中的数据直接拆包



my_high, my_weight, my_age = (178, 100, 18)
print(my_high)
print(my_weight)
print(my_age)


总结:


* 拆包时要注意,需要拆的数据的个数要与变量的个数相同,否则程序会异常
* 除了对元组拆包之外,还可以对列表、字典等拆包

 

In [17]: a, b = (11, 22)
In [18]: a
Out[18]: 11
In [19]: b
Out[19]: 22

In [20]: a, b = [11, 22]
In [21]: a
Out[21]: 11
In [22]: b
Out[22]: 22

In [23]: a, b = {“m”:11, “n”:22} # 取出来的是key,而不是键值对
In [24]: a
Out[24]: ‘m’
In [25]: b
Out[25]: ‘n’



2. 交换2个变量的值



第3种方式

a = 4
b = 5
a, b = b, a

print(a)
print(b)


##### 4.12 函数的引用


在python中,值是靠引用来传递的


我们可以用(id)来判断两个变量是否为同一个值的引用。我们可以将id理解为那块内存的地址标示。



a = 1
b = a
print(id(a)) # 140719292941984
print(id(b)) # 140719292941984 注意两个变量的id值相同

a = 2
print(id(a)) # 140719292942016 注意a的id值已经变了

print(id(b)) # 140719292941984 b的id值依旧


引用(二)


引用当做实参


* 可变类型与不可变类型的变量分别作为函数参数时,会有什么不同吗?
* Python有没有类似C语言中的指针传参呢?



def test1(b): # 变量b一定是一个局部变量,就看它指向的是谁?可变还是不可变
b += b # += 是直接对b指向的空间进行修改,而不是让b指向一个新的
# b = b+b # xx = xx+yyy 先把=号右边的结果计算出来,然后让b指向这个新的地方,不管原来b指向谁
# 现在b一定指向这个新的地方

a = [11, 22]

a = 100
test1(a)
print(a)


总结:


* Python中函数参数是引用传递(注意不是值传递)
* 对于不可变类型,因变量不能修改,所以运算不会影响到变量自身
* 而对于可变类型来说,函数体中的运算有可能会更改传入的参数变量


##### 4.13 可变,不可变类型


总结


* 所谓可变类型与不可变类型是指:数据能够直接进行修改,如果能直接修改那么就是可变,否则是不可变
* 可变类型有: 列表、字典、集合
* 不可变类型有: 数字、字符串、元组


列表:



a = [11, 22] # 可变类型
print(a[0]) # 获取列表的数据,没问题

a[0] = 100
print(a[0]) # 修改列表中的数据,没有问题


元组:



b = (11, 22) # 不可变类型

print(b[0]) # 获取元组的数据,没有问题

b[0] = 100 # 修改元组的数据,程序产生异常

print(b[0])


D:\pythonwork\Harry\venv\Scripts\python.exe C:/Users/admin/Desktop/guiderobot_python_win/pathfinder/apps/Intelligent_lighting/init.py
Traceback (most recent call last):
File “C:/Users/admin/Desktop/guiderobot_python_win/pathfinder/apps/Intelligent_lighting/init.py”, line 5, in
b[0] = 100 #
TypeError: ‘tuple’ object does not support item assignment
11

Process finished with exit code 1


##### 4.14函数的注意事项


1. return 注意事项


一个函数到底有没有返回值,就看有没有return关键字,因为只有return才可以返回数据


当执行完return语句,那么就意味着这个函数的调用完成,return语句后面的代码不会执行


2. 函数名不能重复

 如果在同一个程序中出现了多个相同函数名的函数,那么后面的函数会覆盖前面的函数,在调用函数的时候就可以出现问题,所以要避免函数名称相同
3. 作用域

 在一个函数中定义的变量,只能在本函数中有(局部变量)

 在函数外定义的变量,可以在所有的函数中使用(全局变量)


##### 4.15 函数的应用:学生管理系统



学生的信息可以使用一个字典类型

管理学生可以使用列表

定义全局变量学生列表

student_list = [] # list()

print(“全局变量:”, id(student_list))

显示功能菜单的函数

def show_menu():
print(“-----学生管理系统v1.0-----”)
print(“1. 添加学生”)
print(“2. 删除学生”)
print(“3. 修改学生信息”)
print(“4. 查询学生信息”)
print(“5. 显示所有学生信息”)
print(“6. 退出”)

添加学生

def add_student():
name = input(“请输入学生的姓名:”)
age = input(“请输入学生的年龄:”)
sex = input(“请输入学生的性别:”)

# 定义学生字典类型的变量
student_dict = {} # dict()
# 把学生的信息使用字典进行存储
student_dict["name"] = name
student_dict["age"] = age
student_dict["sex"] = sex
# 这里可以不使用global因为列表是可变类型,可以在原有数据的基础上进行修改,内存地址不变
# 因为列表的内存地址不变,全局变量不需要使用global
# 加上global表示内存地址要发生变化

# 把学生信息添加到学生列表中
student_list.append(student_dict)
# global student_list
# # student_list = [{'name': "李四", "age":"18", "sex":"男"}]
# student_list.append(student_dict)

显示所有学生信息

def show_all_student():
# print(student_list, id(student_list))
for index, student_dict in enumerate(student_list):
# 学号和下标的关系
student_no = index + 1

    print("学号:%d 姓名:%s 年龄:%s 性别:%s" % (student_no, student_dict["name"],
                                       student_dict["age"], student_dict["sex"]))

删除学生信息

def remove_student():
student_no = int(input(“请输入要删除学生的学号:”))
# 获取学生字典信息的下标
index = student_no - 1
if index >= 0 and index < len(student_list):
# 根据下标删除学生信息
del student_list[index]
else:
print(“请输入正确的学号”)

修改学生信息

def modify_student():
student_no = int(input(“请输入要修改学生的学号:”))
# 根据学号计算下标
index = student_no - 1

if index >= 0 and index < len(student_list):
    # 根据下标获取学生字典信息
    student_dict = student_list[index]

    name = input("请输入您修改后的名字:")
    age = input("请输入您修改后的年龄:")
    sex = input("请输入您修改后的性别:")

    student_dict["name"] = name
    student_dict["age"] = age
    student_dict["sex"] = sex
else:
    print("请输入正确的学号")

查询学生

def search_student():
name = input(“请输入要查询的学生姓名:”)

# 遍历学生列表信息
for index, student_dict in enumerate(student_list):
    # pass # 空实现
    if student_dict["name"] == name:
        student_no = index + 1
        # 说明找到了这个学生
        print("学号:%d 姓名:%s 年龄:%s 性别:%s" % (student_no, student_dict["name"],
                                           student_dict["age"], student_dict["sex"]))
        break
else:
    print("对不起,没有找到这个学生")

程序启动的函数

def run():

while True:
    # 显示功能菜单
    show_menu()
    # 接收用户的指令
    menu_option = input("请输入您需要的功能选项:")

    if menu_option == "1":
        print("添加学生")
        add_student()
    elif menu_option == "2":
        print("删除学生")
        remove_student()
    elif menu_option == "3":
        print("修改学生信息")
        modify_student()
    elif menu_option == "4":
        print("查询学生信息")
        search_student()
    elif menu_option == "5":
        print("显示所有学生信息")
        show_all_student()
    elif menu_option == "6":
        print("退出")
        break

执行程序启动的函数

run()


##### 4.16 递归函数


递归函数


在函数内部,可以调用其他函数,如果一个函数在内部调用自己本身,这个函数就是递归函数。


递归函数的特性:


1. 必须有一个明确的结束条件;
2. 每次进入更深一层递归时,问题规模相比上次递归都应有减少
3. 相邻两次重复之间有紧密的联系,前一次要为后一次做准备
4. 递归的效率不高,递归层次过多会导致栈的溢出


例子:


计算机1到100 的和



循环方式

def sum_cycle(n):
sum = 0
for i in range(1, n + 1):
sum += i
print(sum)
sum_cycle(100)



递归方式

def sum_recu(n):

if n > 0:
    return n + sum_recu(n - 1)
else:
    return 0

sum = sum_recu(100)
print(sum)


##### 4.17 匿名函数


1. 函数可以做为参数传递给另外一个函数, 可以使得函数的实现更加通用.
2. 匿名函数也可以作为参数传递给另外一个函数, 对于只需要用到一次函数, 可以通过匿名函数减少代码量.


##### 4.18 推导式


python 语言有一种独特的推导式,相当于语法糖的存在


1. 列表推导式



lis = [x * x for x in range(1, 10)]
print(lis)

[1, 4, 9, 16, 25, 36, 49, 64, 81]

Process finished with exit code 0



lis = []
for i in range(1, 10):
lis.append(i*i)
print(lis)

[1, 4, 9, 16, 25, 36, 49, 64, 81]

Process finished with exit code 0


增加条件语句



print([x * x for x in range(1, 11)])
print([x * x for x in range(1, 11)if x % 2 == 0])

[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
[4, 16, 36, 64, 100]

Process finished with exit code 0


多重循环



print([a + b for a in ‘123’ for b in ‘abc’])

[‘1a’, ‘1b’, ‘1c’, ‘2a’, ‘2b’, ‘2c’, ‘3a’, ‘3b’, ‘3c’]

Process finished with exit code 0


同时循环a和b两个变量


更多应用



dic = {“k1”: “v1”, “k2”: “v2”}
a = [k+“:”+v for k, v in dic.items()]
print(a)

[‘k1:v1’, ‘k2:v2’]

Process finished with exit code 0


2. 字典推导式



dic = {x: x**2 for x in (2, 4, 6)}
print(dic)
print(type(dic))

{2: 4, 4: 16, 6: 36}
<class ‘dict’>
Process finished with exit code 0


3.集合推导式



a = {x for x in ‘abracadabra’ if x not in ‘abc’}
print(a)
print(type(a))

{‘d’, ‘r’}
<class ‘set’>

Process finished with exit code 0


没有元组推导式



tup = (x for x in range(9))
print(tup)
print(type(tup))

<generator object at 0x000001FAE48C8900>
<class ‘generator’>
Process finished with exit code 0


##### 4.19 set集合set,list,tuple之间的类型转换


set 是集合类型



a = set()
print(type(a))
b = [1, 2, 3, 12, 3, 1, 3]
print(b)
print(set(b))

<class ‘set’>
[1, 2, 3, 12, 3, 1, 3]
{1, 2, 3, 12}
Process finished with exit code 0


set, list, tuple,之间可以相互转换



c = {1, 2}
d = list©
print(d)
print(type©)

[1, 2]
<class ‘set’>

Process finished with exit code 0



d = [1, 2, 3, 12]
e = tuple(d)
print(e)

(1, 2, 3, 12)
Process finished with exit code 0



e = (1, 2, 3, 12)
f = list(e)
print(f)

[1, 2, 3, 12]

Process finished with exit code 0


使用set,可以快速的完成对list中的元素去重复的功能


##### 4.20高级函数


高阶函数: 函数的参数是一个函数类型


高阶函数:函数的返回值是一个函数类型



def calc_num(new_func):
a = 1
b = 2

# 执行外界传入过来的函数
result = new_func(a, b)

return result

def sum_num(num1, num2):
return num1 + num2

调用函数

result = calc_num(sum_num)
print(result)


3
Process finished with exit code 0



def show():

# 在python里面可以函数里面在定义一个函数
def print_info():
    print("哈哈, 我是一个子函数")

# 函数的返回值是一个函数类型
return print_info

new_func = show()

print(new_func, type(new_func))

调用返回的函数

new_func()

<function show..print_info at 0x00000265C90AA160> <class ‘function’>
哈哈, 我是一个子函数
Process finished with exit code 0


1. reduce 用法


reduce()根据函数对容器类型中每一个数据进行计算.


第一个参数功能函数,函数需要带有两个参数


第二个参数是要操作的容器类型


计算列表中的累加和:



import functools

my_list = [1, 2, 3, 4, 5]

def f(x1, x2):
return x1 + x2

result = functools.reduce(f, my_list)
print(result)


#### 5.文件操作


##### 5.1 文件操作介绍


<1>什么是文件


<2>文件的作用


大家应该听说过一句话:“好记性不如烂笔头”。


不仅人的大脑会遗忘事情,计算机也会如此,比如一个程序在运行过程中用了九牛二虎之力终于计算出了结果,试想一下如果不把这些数据存放起来,相比重启电脑之后,“哭都没地方哭了”


可见,在把数据存储起来有做么大的价值


使用文件的目的:



> 
> 就是把一些存储存放起来,可以让程序下一次执行的时候直接使用,而不必重新制作一份,省时省力
> 
> 
> 


##### 5.2 文件的读写


<1>写数据(write)


使用write()可以完成向文件写入数据


demo: 新建一个文件 `file_write_test.py`,向其中写入如下代码:



f = open(‘test.txt’, ‘w’)
f.write(‘hello world, i am here!’)
f.close()


运行之后会在`file_write_test.py`文件所在的路径中创建一个文件`test.txt`,其中数据如下:



hello world, i am here!


注意:


* 如果文件不存在那么创建,如果存在那么就先清空,然后写入数据


<2>读数据(read)


使用read(num)可以从文件中读取数据,num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据


demo: 新建一个文件`file_read_test.py`,向其中写入如下代码:



f = open(‘test.txt’, ‘r’)
content = f.read(5) # 最多读取5个数据
print(content)

print(“-”*30) # 分割线,用来测试

content = f.read() # 从上次读取的位置继续读取剩下的所有的数据
print(content)

f.close() # 关闭文件,这个可以是个好习惯哦


运行现象:



hello

world, i am here!


注意:


* 如果用open打开文件时,如果使用的"r",那么可以省略,即只写 `open('test.txt')`


<3>读数据(readlines)


就像read没有参数时一样,readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素



#coding=utf-8

f = open(‘test.txt’, ‘r’)
content = f.readlines()
print(type(content))

i=1
for temp in content:
print(“%d:%s” % (i, temp))
i += 1

f.close()


<4>读数据(readline)



#coding=utf-8

f = open(‘test.txt’, ‘r’)

content = f.readline()
print(“1:%s” % content)

content = f.readline()
print(“2:%s” % content)

f.close()


##### 5.3 应用1:制作文件的备份


任务描述


* 输入文件的名字,然后程序自动完成对文件进行备份


参考代码



提示输入文件

oldFileName = input(“请输入要拷贝的文件名字:”)

以读的方式打开文件

oldFile = open(oldFileName,‘rb’)

提取文件的后缀

fileFlagNum = oldFileName.rfind(‘.’)
if fileFlagNum > 0:
fileFlag = oldFileName[fileFlagNum:]

组织新的文件名字

newFileName = oldFileName[:fileFlagNum] + ‘[复件]’ + fileFlag

创建新文件

newFile = open(newFileName, ‘wb’)

把旧文件中的数据,一行一行的进行复制到新文件中

for lineContent in oldFile.readlines():
newFile.write(lineContent)

关闭文件

oldFile.close()
newFile.close()


##### 5.4 文件的相关操作


有些时候,需要对文件进行重命名、删除等一些操作,python的os模块中都有这么功能


1.文件重命名


os模块中的rename()可以完成对文件的重命名操作


rename(需要修改的文件名, 新的文件名)



import os
os.rename(“毕业论文.txt”, “毕业论文-最终版.txt”)


2.删除文件


os模块中的remove()可以完成对文件的删除操作


remove(待删除的文件名)



import os
os.remove(“毕业论文.txt”)


3.创建文件夹



import os
os.mkdir(“张三”)


4.获取当前目录



import os
os.getcwd()


5. 改变默认目录



import os
os.chdir(“…/”)


6. 获取目录列表



import os
os.listdir(“./”)


7. 删除文件夹



import os
os.rmdir(“张三”)


##### 5.5应用:批量修改文件名


<1>运行过程演示


* 运行程序之前


<2>参考代码



#coding=utf-8

批量在文件名前加前缀

import os

funFlag = 1 # 1表示添加标志 2表示删除标志
folderName = ‘./renameDir/’

获取指定路径的所有文件名字

dirList = os.listdir(folderName)

遍历输出所有文件名字

for name in dirList:
print name

if funFlag == 1:
    newName = '[东哥出品]-' + name
elif funFlag == 2:
    num = len('[东哥出品]-')
    newName = name[num:]
print newName

os.rename(folderName+name, folderName+newName)

##### 5.6综合应用


学生管理系统(文件版)



学生的信息可以使用一个字典类型

管理学生可以使用列表

import os

定义全局变量学生列表

student_list = [] # list()
print(“全局变量:”, id(student_list))

显示功能菜单的函数

def show_menu():
print(“-----学生管理系统v1.0-----”)
print(“1. 添加学生”)
print(“2. 删除学生”)
print(“3. 修改学生信息”)
print(“4. 查询学生信息”)
print(“5. 显示所有学生信息”)
print(“6. 退出”)

添加学生

def add_student():
name = input(“请输入学生的姓名:”)
age = input(“请输入学生的年龄:”)
sex = input(“请输入学生的性别:”)

# 定义学生字典类型的变量
student_dict = {} # dict()
# 把学生的信息使用字典进行存储
student_dict["name"] = name
student_dict["age"] = age
student_dict["sex"] = sex
# 这里可以不使用global因为列表是可变类型,可以在原有数据的基础上进行修改,内存地址不变
# 因为列表的内存地址不变,全局变量不需要使用global
# 加上global表示内存地址要发生变化

# 把学生信息添加到学生列表中
student_list.append(student_dict)
# global student_list
# # student_list = [{'name': "李四", "age":"18", "sex":"男"}]
# student_list.append(student_dict)

显示所有学生信息

def show_all_student():
# print(student_list, id(student_list))
for index, student_dict in enumerate(student_list):
# 学号和下标的关系
student_no = index + 1

    print("学号:%d 姓名:%s 年龄:%s 性别:%s" % (student_no, student_dict["name"],
                                       student_dict["age"], student_dict["sex"]))

删除学生信息

def remove_student():
student_no = int(input(“请输入要删除学生的学号:”))
# 获取学生字典信息的下标
index = student_no - 1
if index >= 0 and index < len(student_list):
# 根据下标删除学生信息
del student_list[index]
else:
print(“请输入正确的学号”)

修改学生信息

def modify_student():
student_no = int(input(“请输入要修改学生的学号:”))
# 根据学号计算下标
index = student_no - 1

if index >= 0 and index < len(student_list):
    # 根据下标获取学生字典信息
    student_dict = student_list[index]

    name = input("请输入您修改后的名字:")
    age = input("请输入您修改后的年龄:")
    sex = input("请输入您修改后的性别:")

    student_dict["name"] = name
    student_dict["age"] = age
    student_dict["sex"] = sex
else:
    print("请输入正确的学号")

查询学生

def search_student():
name = input(“请输入要查询的学生姓名:”)

# 遍历学生列表信息
for index, student_dict in enumerate(student_list):
    # pass # 空实现
    if student_dict["name"] == name:
        student_no = index + 1
        # 说明找到了这个学生
        print("学号:%d 姓名:%s 年龄:%s 性别:%s" % (student_no, student_dict["name"],
                                           student_dict["age"], student_dict["sex"]))
        break
else:
    print("对不起,没有找到这个学生")

保存学生列表数据到文件中

def save_data():
file = open(“student_list.data”, “w”, encoding=“utf-8”)
# 把列表转成字符串
student_list_str = str(student_list)
# 把列表数据写入到文件中
file.write(student_list_str)
file.close()

加载文件中的数据

def load_data():

result = os.path.exists("Test")
print(result)
# 判断文件或者文件夹是否存在
if os.path.exists("student_list.data"):
    file = open("student_list.data", "r", encoding="utf-8")

    # 读取文件中的数据
    file_content = file.read()
    new_student_list = eval(file_content)
    print(new_student_list, type(new_student_list))
    # global student_list
    # student_list = new_student_list

    student_list.extend(new_student_list)
    print("全局变量:", id(student_list))

    file.close()

程序启动的函数

def run():

# 加载文件中的数据
load_data()

while True:
    # 显示功能菜单
    show_menu()
    # 接收用户的指令
    menu_option = input("请输入您需要的功能选项:")

    if menu_option == "1":
        print("添加学生")
        add_student()
    elif menu_option == "2":
        print("删除学生")
        remove_student()
    elif menu_option == "3":
        print("修改学生信息")
        modify_student()
    elif menu_option == "4":
        print("查询学生信息")
        search_student()
    elif menu_option == "5":
        print("显示所有学生信息")
        show_all_student()
    elif menu_option == "6":
        # 保存数据到文件
        save_data()
        print("退出")
        break

执行程序启动的函数

run()


#### 6.面向对象


##### 6.1面向对象编程介绍


面向对象


1. 概述


如今主流的软件开发思想有两种:一个是**面向过程**,另一个是**面向对象**。


面向过程出现得较早,典型代表为C语言,开发中小型项目的效率很高,但是很难适用于如今主流的大中型项目开发场景。面向对象则出现得更晚一些,典型代表为Java或C++等语言,更加适合用于大型开发场景。两种开发思想各有长短。


对于**面向过程**的思想: 需要实现一个功能的时候,看重的是开发的步骤和过程,每一个步骤都需要自己亲力亲为,需要自己编写代码(自己来做)


对于**面向对象**的思想:当需要实现一个功能的时候,看重的并不是过程和步骤,而是关心谁帮我做这件事(偷懒,找人帮我做)


面向对象的**三大特征**有:**封装性、继承性、多态性**。


2. 生活举例
3. 洗衣服

 1.1. 面向过程(手洗):脱衣服、找一个盆、加水、加洗衣粉、浸泡30分钟、搓洗、拧衣服、倒掉水、再加水、漂洗、拧衣服、倒掉水、晾衣服。

 1.2. 面向对象(机洗):脱衣服、放入洗衣机、按下开关、拿出衣服晾晒。
4. 买电脑

 2.1 面向过程(自己买):需要电脑、查询参数信息、横向比较机型、了解打折信息、与店家讨价还价、下单、收快递、开机验货、确认收货。

 2.2 面向对象(找人买):需要电脑、找秘书帮我买、收电脑。


##### 6.2 类和对象


面向对象编程的2个非常重要的概念:类和对象


对象是面向对象编程的核心,在使用对象的过程中,为了将具有共同特征和行为的一组对象抽象定义,提出了另外一个新的概念——类


类就相当于制造飞机时的图纸,用它来进行创建的飞机就相当于对象


1. 类



人以类聚 物以群分。
具有相似内部状态和运动规律的实体的集合(或统称为抽象)。
具有相同属性和行为事物的统称


类是抽象的,在使用的时候通常会找到这个类的一个具体的存在,使用这个具体的存在。一个类可以找到多个对象


2. 对象



某一个具体事物的存在 ,在现实世界中可以是看得见摸得着的。

可以是直接使用的


3. 类和对象之间的关系


小总结:类就是创建对象的模板


4. 练习:区分类和对象



奔驰汽车 类
奔驰smart 类
张三的那辆奔驰smart 对象
狗 类
大黄狗 类
李四家那只大黄狗 对象
水果 类
苹果 类
红苹果 类 红富士苹果 类
我嘴里吃了一半的苹果 对象


5. 类的构成


类(Class) 由3个部分构成


* 类的名称:类名
* 类的属性:一组数据
* 类的方法:允许对进行操作的方法 (行为)


5.1. 举例:


1)人类设计,只关心3样东西:


* 事物名称(类名):人(Person)
* 属性:身高(height)、年龄(age)
* 方法(行为/功能):跑(run)、打架(fight)


2)狗类的设计


* 类名:狗(Dog)
* 属性:品种 、毛色、性别、名字、 腿儿的数量
* 方法(行为/功能):叫 、跑、咬人、吃、摇尾巴


6. 类的抽象


如何把日常生活中的事物抽象成程序中的类?


拥有相同(或者类似)属性和行为的对象都可以抽像出一个类


方法:一般名词都是类(名词提炼法)


6.1. 坦克发射3颗炮弹轰掉了2架飞机


* 坦克–》可以抽象成 类
* 炮弹–》可以抽象成类
* 飞机-》可以抽象成类


6.2. 小明在公车上牵着一条叼着热狗的狗


* 小明–》 人类
* 公车–》 交通工具类
* 热狗–》 食物类


##### 6.3定义类


定义一个类,格式如下:



class 类名:
方法列表


demo:定义一个Hero类



class Hero: # 经典类(旧式类)定义形式

class Hero():

class Hero(object): # 新式类定义形式
def info(self):
print(“英雄各有见,何必问出处。”)


说明:


* 定义类时有2种形式:新式类和经典类,上面代码中的Hero为新式类,前两行注释部分则为经典类;
* object 是Python 里所有类的最顶级父类;
* 类名 的命名规则按照"大驼峰命名法";
* info 是一个实例方法,第一个参数一般是self,表示实例对象本身,当然了可以将self换为其它的名字,其作用是一个变量 这个变量指向了实例对象


##### 6.4 创建对象


python中,可以根据已经定义的类去创建出一个或多个对象。


创建对象的格式为:



对象名1 = 类名()
对象名2 = 类名()
对象名3 = 类名()


创建对象demo:



class Hero(object): # 新式类定义形式
“”“info 是一个实例方法,类对象可以调用实例方法,实例方法的第一个参数一定是self”“”
def info(self):
“”“当对象调用实例方法时,Python会自动将对象本身的引用做为参数,
传递到实例方法的第一个参数self里”“”
print(self)
print(“self各不同,对象是出处。”)

Hero这个类 实例化了一个对象 taidamier(泰达米尔)

taidamier = Hero()

对象调用实例方法info(),执行info()里的代码

. 表示选择属性或者方法

taidamier.info()

print(taidamier) # 打印对象,则默认打印对象在内存的地址,结果等同于info里的print(self)
print(id(taidamier)) # id(taidamier) 则是内存地址的十进制形式表示


##### 6.5添加和获取对象的属性



class Hero(object):
“”“定义了一个英雄类,可以移动和攻击”“”
def move(self):
“”“实例方法”“”
print(“正在前往事发地点…”)

def attack(self):
    """实例方法"""
    print("发出了一招强力的普通攻击...")

实例化了一个英雄对象 泰达米尔

taidamier = Hero()

给对象添加属性,以及对应的属性值

taidamier.name = “泰达米尔” # 姓名
taidamier.hp = 2600 # 生命值
taidamier.atk = 450 # 攻击力
taidamier.armor = 200 # 护甲值

通过.成员选择运算符,获取对象的属性值

print(“英雄 %s 的生命值 :%d” % (taidamier.name, taidamier.hp))
print(“英雄 %s 的攻击力 :%d” % (taidamier.name, taidamier.atk))
print(“英雄 %s 的护甲值 :%d” % (taidamier.name, taidamier.armor))

通过.成员选择运算符,获取对象的实例方法

taidamier.move()
taidamier.attack()


##### 6.6在方法内通过self获取对象属性



class Hero(object):
“”“定义了一个英雄类,可以移动和攻击”“”
def move(self):
“”“实例方法”“”
print(“正在前往事发地点…”)

def attack(self):
    """实例方法"""
    print("发出了一招强力的普通攻击...")

def info(self):
    """在类的实例方法中,通过self获取该对象的属性"""
    print("英雄 %s 的生命值 :%d" % (self.name, self.hp))
    print("英雄 %s 的攻击力 :%d" % (self.name, self.atk))
    print("英雄 %s 的护甲值 :%d" % (self.name, self.armor))

实例化了一个英雄对象 泰达米尔

taidamier = Hero()

给对象添加属性,以及对应的属性值

taidamier.name = “泰达米尔” # 姓名
taidamier.hp = 2600 # 生命值
taidamier.atk = 450 # 攻击力
taidamier.armor = 200 # 护甲值

通过.成员选择运算符,获取对象的实例方法

taidamier.info() # 只需要调用实例方法info(),即可获取英雄的属性
taidamier.move()
taidamier.attack()


#### 7. 异常,模块


##### 7.1 异常


异常:


当python检查到一个错误时,解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的“异常”


##### 7.2 捕获异常


案例剖析


1. 捕获异常 try…except…


看如下示例:



try:
print(‘-----test–1—’)
open(‘123.txt’,‘r’)
print(‘-----test–2—’)
except IOError:
pass


运行结果:



-----test–1—

Process finished with exit code 0


说明:


* 此程序看不到任何错误,因为用except 捕获到了IOError异常,并添加了处理的方法
* pass 表示实现了相应的实现,但什么也不做;如果把pass改为print语句,那么就会输出其他信息


小总结:



try:
print(‘-----test–1—’)
open(‘123.txt’,‘r’)
print(‘-----test–2—’)
# 解释 可能产生异常的代码;放在try中

except IOError:
pass # 解释 如果产生错误时处理的方法


* 把可能出现问题的代码,放在try中
* 把处理异常的代码,放在except中


2. except捕获多个异常


看如下示例:



try:
print num
except IOError:
print(‘产生错误了’)


运行结果如下:



Traceback (most recent call last):
File “D:/work/test.py”, line 2, in
print(num)
NameError: name ‘num’ is not defined

Process finished with exit code 1


想一想:



> 
> 上例程序,已经使用except来捕获异常了,为什么还会看到错误的信息提示?
> 
> 
> 


答:



> 
> except捕获的错误类型是IOError,而此时程序产生的异常为 NameError ,所以except没有生效
> 
> 
> 


修改后的代码为:



try:
print num
except NameError:
print(‘产生错误了’)


运行结果如下:



File “D:/work/test.py”, line 2
print num
^
SyntaxError: Missing parentheses in call to ‘print’. Did you mean print(num)?

Process finished with exit code 1


实际开发中,捕获多个异常的方式,如下:



#coding=utf-8
try:
print(‘-----test–1—’)
open(‘123.txt’,‘r’) # 如果123.txt文件不存在,那么会产生 IOError 异常
print(‘-----test–2—’)
print(num)# 如果num变量没有定义,那么会产生 NameError 异常

except (IOError,NameError):
#如果想通过一次except捕获到多个异常可以用一个元组的方式


注意:


* 当捕获多个异常时,可以把要捕获的异常的名字,放到except 后,并使用元组的方式仅进行存储


3. 获取异常的信息描述
4. 捕获所有异常
5. else


咱们应该对`else`并不陌生,在if中,它的作用是当条件不满足时执行的实行;同样在try…except…中也是如此,即如果没有捕获到异常,那么就执行else中的事情



try:
num = 100
print(“num”)
except NameError as errorMsg:
print(‘产生错误了:%s’%errorMsg)
else:
print(‘没有捕获到异常,真高兴’)


运行结果如下:



num
没有捕获到异常,真高兴
Process finished with exit code 0


6. try…finally…


try…finally…语句用来表达这样的情况:



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


demo:



import time
try:
f = open(‘test.txt’)
try:
while True:
content = f.readline()
if len(content) == 0:
break
time.sleep(2)
print(content)
except:
#如果在读取文件的过程中,产生了异常,那么就会捕获到
#比如 按下了 ctrl+c
pass
finally:
f.close()
print(‘关闭文件’)
except:
print(“没有这个文件”)


说明:



> 
> test.txt文件中每一行数据打印,但是我有意在每打印一行之前用time.sleep方法暂停2秒钟。这样做的原因是让程序运行得慢一些。在程序运行的时候,按Ctrl+c中断(取消)程序。
> 
> 
> 我们可以观察到KeyboardInterrupt异常被触发,程序退出。但是在程序退出之前,finally从句仍然被执行,把文件关闭。
> 
> 
> 


##### 7.3 异常的传递


1. try嵌套中



import time
try:
f = open(‘test.txt’)
try:
while True:
content = f.readline()
if len(content) == 0:
break
time.sleep(2)
print(content)
finally:
f.close()
print(‘关闭文件’)
except:
print(“没有这个文件”)


运行结果:



In [26]: import time
…: try:
…: f = open(‘test.txt’)
…: try:
…: while True:
…: content = f.readline()
…: if len(content) == 0:
…: break
…: time.sleep(2)
…: print(content)
…: finally:
…: f.close()
…: print(‘关闭文件’)
…: except:
…: print(“没有这个文件”)
…: finally:
…: print(“最后的finally”)
…:
xxxxxxx—>这是test.txt文件中读取到信息
^C关闭文件
没有这个文件
最后的finally


2. 函数嵌套调用中



def test1():
    print("----test1-1----")
    print(num)
    print("----test1-2----")

def test2():
    print("----test2-1----")
    test1()
    print("----test2-2----")

def test3():
    try:
        print("----test3-1----")
        test1()
        print("----test3-2----")
    except Exception as result:
        print("捕获到了异常,信息是:%s"%result)

    print("----test3-2----")

test3()
print("------华丽的分割线-----")
test2()

总结:


* 如果try嵌套,那么如果里面的try没有捕获到这个异常,那么外面的try会接收到这个异常,然后进行处理,如果外边的try依然没有捕获到,那么再进行传递。。。
* 如果一个异常是在一个函数中产生的,例如函数A---->函数B---->函数C,而异常是在函数C中产生的,那么如果函数C中没有对这个异常进行处理,那么这个异常会传递到函数B中,如果函数B有异常处理那么就会按照函数B的处理方式进行执行;如果函数B也没有异常处理,那么这个异常会继续传递,以此类推。。。如果所有的函数都没有处理,那么此时就会进行异常的默认处理,即通常见到的那样
* 注意观察上图中,当调用test3函数时,在test1函数内部产生了异常,此异常被传递到test3函数中完成了异常处理,而当异常处理完后,并没有返回到函数test1中进行执行,而是在函数test3中继续执行


##### 7.4 抛出自定义的异常


抛出自定义的异常


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


下面是一个引发异常的例子:



class ShortInputException(Exception):
“”" 自定义的异常类 “”"
def init(self, length, least):
# super().init()
self.length = length
self.least = least

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

main()


注意


* 以上程序中,关于代码

 

super().init()

 的说明



> 
> 这一行代码,可以调用也可以不调用,建议调用,因为`__init__`方法往往是用来对创建完的对象进行初始化工作,如果在子类中重写了父类的`__init__`方法,即意味着父类中的很多初始化工作没有做,这样就不保证程序的稳定了,所以在以后的开发中,如果重写了父类的`__init__`方法,最好是先调用父类的这个方法,然后再添加自己的功能
> 
> 
>


##### 7.5 模块介绍


模块


1. Python中的模块


有过C语言编程经验的朋友都知道在C语言中如果要引用`sqrt函数`,必须用语句`#include <math.h>`引入math.h这个头文件,否则是无法正常进行调用的。


那么在Python中,如果要引用一些其他的函数,该怎么处理呢?


在Python中有一个概念叫做模块(module),这个和C语言中的头文件以及Java中的包很类似,比如在Python中要调用`sqrt函数`,必须用import关键字引入math这个模块,下面就来了解一下Python中的模块。


说的通俗点:模块就好比是工具包,要想使用这个工具包中的工具(就好比函数),就需要导入这个模块


2. import


在Python中用关键字`import`来引入某个模块,比如要引用模块math,就可以在文件最开始的地方用import math来引入。


形如:



import module1,mudule2...

当解释器遇到import语句,如果模块在当前的搜索路径就会被导入。


在调用math模块中的函数时,必须这样引用:



模块名.函数名


* 想一想:



> 
> 为什么必须加上模块名调用呢?
> 
> 
>
* 答:



> 
> 因为可能存在这样一种情况:在多个模块中含有相同名称的函数,此时如果只是通过函数名来调用,解释器无法知道到底要调用哪个函数。所以如果像上述这样引入模块的时候,调用函数必须加上模块名
> 
> 
>



import math

#这样会报错
print sqrt(2)

#这样才能正确输出结果
print math.sqrt(2)

有时候我们只需要用到模块中的某个函数,只需要引入该函数即可,此时可以用下面方法实现:



from 模块名 import 函数名1,函数名2....

不仅可以引入函数,还可以引入一些全局变量、类等


* 注意:



> 
> 
> 	+ 通过这种方式引入的时候,调用函数时只能给出函数名,不能给出模块名,但是当两个模块中含有相同名称函数的时候,后面一次引入会覆盖前一次引入。也就是说假如模块A中有函数function( ),在模块B中也有函数function( ),如果引入A中的function在先、B中的function在后,那么当调用function函数的时候,是去执行模块B中的function函数。
> 	+ 如果想一次性引入math中所有的东西,还可以通过from math import \*来实现
>


3. from…import


Python的from语句让你从模块中导入一个指定的部分到当前命名空间中


语法如下:



from modname import name1[, name2[, ... nameN]]

例如,要导入模块fib的fibonacci函数,使用如下语句:



from fib import fibonacci

注意


* 不会把整个fib模块导入到当前的命名空间中,它只会将fib里的fibonacci单个引入


4. from … import \*


把一个模块的所有内容全都导入到当前的命名空间也是可行的,只需使用如下声明:



from modname import *

注意


* 这提供了一个简单的方法来导入一个模块中的所有项目。然而这种声明不该被过多地使用。


5. as



In [1]: import time as tt

In [2]: time.sleep(1)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-2-07a34f5b1e42> in <module>()
----> 1 time.sleep(1)

NameError: name 'time' is not defined

In [3]: 

In [3]: 

In [3]: tt.sleep(1)

In [4]: 

In [4]: 

In [4]: from time import sleep as sp

In [5]: sleep(1)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-5-82e5c2913b44> in <module>()
----> 1 sleep(1)

NameError: name 'sleep' is not defined

In [6]: 

In [6]: 

In [6]: sp(1)

In [7]:

6. 定位模块


当你导入一个模块,Python解析器对模块位置的搜索顺序是:


1. 当前目录
2. 如果不在当前目录,Python则搜索在shell变量PYTHONPATH下的每个目录。
3. 如果都找不到,Python会察看默认路径。UNIX下,默认路径一般为/usr/local/lib/python/
4. 模块搜索路径存储在system模块的sys.path变量中。变量里包含当前目录,PYTHONPATH和由安装过程决定的默认目录。


##### 7.6模块制作


1. 定义自己的模块


在Python中,每个Python文件都可以作为一个模块,模块的名字就是文件的名字。


比如有这样一个文件test.py,在test.py中定义了函数add


test.py



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

2. 调用自己定义的模块


那么在其他文件中就可以先import test,然后通过test.add(a,b)来调用了,当然也可以通过from test import add来引入


main.py



import test

result = test.add(11,22)
print(result)

3. 测试模块


在实际开中,当一个开发人员编写完一个模块后,为了让模块能够在项目中达到想要的效果,这个开发人员会自行在py文件中添加一些测试信息,例如:



test.py
def add(a,b):
return a+b

# 用来进行测试
ret = add(12,22)
print('int test.py file,,,,12+22=%d'%ret)

如果此时,在其他py文件中引入了此文件的话,想想看,测试的那段代码是否也会执行呢!



main.py
import test

result = test.add(11,22)
print(result)

运行现象:


至此,可发现test.py中的测试代码,应该是单独执行test.py文件时才应该执行的,不应该是其他的文件中引用而执行


为了解决这个问题,python在执行一个文件时有个变量`__name__`


直接运行此文件


在其他文件中import此文件


总结:


* 可以根据\_\_name\_\_变量的结果能够判断出,是直接执行的python脚本还是被引入执行的,从而能够有选择性的执行测试代码


##### 7.7模块中的`__all__`


1. 没有`__all__`
2. 模块中有`__all__`


总结


* 如果一个文件中有\_\_all\_\_变量,那么也就意味着这个变量中的元素,不会被from xxx import \*时导入


##### 7.8 python中的包




现在能在网上找到很多很多的学习资源,有免费的也有收费的,当我拿到1套比较全的学习资源之前,我并没着急去看第1节,我而是去审视这套资源是否值得学习,有时候也会去问一些学长的意见,如果可以之后,我会对这套学习资源做1个学习计划,我的学习计划主要包括规划图和学习进度表。



分享给大家这份我薅到的免费视频资料,质量还不错,大家可以跟着学习

![](https://img-blog.csdnimg.cn/img_convert/21b2604bd33c4b6713f686ddd3fe5aff.png)



**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化学习资料的朋友,可以戳这里无偿获取](https://bbs.csdn.net/topics/618317507)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
  • 24
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值