Python 基础知识
1. 认识 Python
1.1 Python 概述
1.1.1 基本概念
1.1.2 语言优势
2020年2月的TIOBE的编程语言排行榜:
Python也存在缺点:
1.1.3 典型应用
1.2 安装Python环境
1.2.1 下载Python
目前最新版是3.8.2
1.2.2 安装Python
1.2.3 配置环境变量
Python的安装路径,及其Script文件夹
1.2.4 下载并配置Pycharm
- Python文件模板配置
# -*- codeing = utf-8 -*-
# @Time :${DATE} ${TIME}
# @Author: Michael
# @File : ${NAME}.py
# @Software: ${PRODUCT_NAME}
- 字体设置
- 课堂练习:
下载并安装Python环境(10分钟)
1.3 编写第一个Python程序
1.4 注释
- 单行注释
以#开头,#右边的所有东西当做说明,而不是真正要执行的程序,起辅助说明作用
# 我是注释,可以在里写一些功能说明之类的哦
print('hello world')
- 多行注释
'''
我是多行注释,
可以写很多很多行的功能说明
哈哈哈。。。
'''
print('hello world')
- python程序中,中文支持
如果直接在程序中用到了中文,比如
print('你好')
如果直接运行输出,程序会出错。
解决的办法为:在程序的开头写入如下代码,这就是中文注释
#coding=utf-8
修改之后的程序:
#coding=utf-8
print('你好')
运行结果:
你好
- 注意:
在python的语法规范中推荐使用的方式:
# -*- coding:utf-8 -*-
- 课堂练习:
编写第一个Python程序,并配置好Pycharm(10分钟)
1.5 变量及类型
1.6 标识符和关键字
- 什么是关键字
python一些具有特殊功能的标示符,这就是所谓的关键字
关键字,是python已经使用的了,所以不允许开发者自己定义和关键字相同的名字的标示符
- 查看关键字:
>>> import keyword
>>> keyword.kwlist
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
1.7 输出
1.7.1 普通输出
- python中普通的输出
# 打印提示
print('hello world')
1.7.2 格式化输出
1.7.2.1 格式化操作的目的
比如有以下代码:
pirnt("我今年10岁")
pirnt("我今年11岁")
pirnt("我今年12岁")
...
- 想一想:
在输出年龄的时候,用了多次"我今年xx岁",能否简化一下程序呢???
- 答:
字符串格式化
1.7.2.2 什么是格式化
看如下代码:
age = 10
print("我今年%d岁"%age)
age += 1
print("我今年%d岁"%age)
age += 1
print("我今年%d岁"%age)
在程序中,看到了 % 这样的操作符,这就是Python中格式化输出。
age = 18
name = "xiaohua"
print("我的姓名是%s,年龄是%d"%(name,age))
1.7.2.3 常用的格式符号
下面是完整的,它可以与%符号使用列表:
1.7.3 换行输出
在输出的时候,如果有 \n 那么,此时 \n 后的内容会在另外一行显示
1.8 输入
运行结果:
- input()的小括号中放入的是,提示信息,用来在获取数据之前给用户的一个简单提示
- input()在从键盘获取了数据以后,会存放到等号左边的变量中
- input()函数接受的输入必须是表达式
>>> a = input()
123
>>> a
123
>>> type(a)
<type 'int'>
>>> a = input()
abc
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <module>
NameError: name 'abc' is not defined
>>> a = input()
"abc"
>>> a
'abc'
>>> type(a)
<type 'str'>
>>> a = input()
1+3
>>> a
4
>>> a = input()
"abc"+"def"
>>> a
'abcdef'
>>> value = 100
>>> a = input()
value
>>> a
100
1.9运算符和表达式
2.判断语句和循环语句
2.1 条件判断语句
- if语句是用来进行判断的,其使用格式如下:
- demo:
- 运行结果:
2.1.1 if-else
- 代码的缩进为一个tab键,或者4个空格
if True:
print ("Answer")
print ("True")
else:
print ("Answer")
print ("False") # 缩进不一致,会导致运行错误
2.1.2 elif
- demo:
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:
else: #elif可以else一起使用
print('本次考试,等级为E')
- 注意
- 可以和else一起使用
- elif必须和if一起使用,否则出错
2.1.3 if嵌套
2.1.3.1 if嵌套的格式
if 条件1:
满足条件1 做的事情1
满足条件1 做的事情2
...(省略)...
if 条件2:
满足条件2 做的事情1
满足条件2 做的事情2
...(省略)...
- 说明
- 外层的if判断,也可以是if-else
- 内层的if判断,也可以是if-else
- 根据实际开发的情况,进行选择
2.1.3.2 if嵌套的应用
demo:
xingBie = 1 # 用1代表男生,0代表女生
danShen = 1 # 用1代表单身,0代表有男/女朋友
if xingBie == 1:
print("是男生")
if danShen == 1:
print("我给你介绍一个吧?")
else:
print("你给我介绍一个呗?")
else:
print("你是女生")
print("……")
2.1.3.2 import 与 from…import
在 python 用 import 或者 from…import 来导入相应的模块。
将整个模块(somemodule)导入,格式为: import somemodule
从某个模块中导入某个函数,格式为: from somemodule import somefunction
从某个模块中导入多个函数,格式为: from somemodule import firstfunc, secondfunc, thirdfunc
将某个模块中的全部函数导入,格式为: **from somemodule import **
【生成随机数】
- 第一行代码引入库:
import random #引入随机库
- 生成指定范围的随机数
computer = random.randint(0,2) #随机生成0、1、2中的一个数字,赋值给变量computer
课堂练习:
综合使用if语句的相关知识,实现石头剪子布游戏效果。显示下面提示信息:
请输入:剪刀(0)、石头(1)、布(2):_
用户输入数字0-2中的一个数字,与系统随机生成的数字比较后给出结果信息。
例如:输入0后,显示如下
你的输入为:剪刀(0)
随机生成数字为:1
哈哈,你输了:)
提示:对于输入不正常的情况尽可能考虑全面,使程序能够正常运行。
建议用时15~20分钟。
# 5次循环处理猜拳,用了函数,循环,import随机数
import random
# shift is for xxx
def shift():
computer = random.randint(0, 2)
human = input("请输入:剪刀(0)、石头(1)、布(2):_")
print("computer is", computer)
print("human is", human)
result = computer - int(human)
if result == 1 or result == -2:
print("computer is winner")
elif result == 0:
print("The two sides tied")
else:
print("human is winner")
for i in range(5):
shift()
2.2 循环语句
2.2.1 for循环
for循环的格式
for 临时变量 in 列表或者字符串等:
循环满足条件时执行的代码
demo:
name = 'chengdu'
for x in name:
print(x)
for i in range(5)
print(i)
for i in range(1, 5, 2) #起始值,上限, 步长
2.2.2 while循环
demo
i = 0
while i<5:
print("当前是第%d次执行循环"%(i+1))
print("i=%d"%i)
i+=1
**课堂练习: **
- 计算1~100的累积和(包含1和100)
- 计算1~100之间偶数的累积和(包含1和100)
建议用时20分钟。
# encoding=utf-8
result = 0
for i in range(101):
result += i
print(result)
result = 0
for i in range(1, 101, 2):
result += i
print(result)
2.2.3 break和continue
- 带有break的循环示例如下:
i = 0
while i<10:
i = i+1
print('----')
if i==5:
break
print(i)
- 带有continue的循环示例如下:
i = 0
while i<10:
i = i+1
print('----')
if i==5:
continue
print(i)
作业:
使用for循环和while循环,打印九九乘法表,显示效果如下图:
for x in range(1, 10):
for y in range(1, x+1):
print("%d*%d=%d\t" %(y, x, x*y), end="")
print()
x = 1
while x < 10:
y = 1
while y < x+1:
print("{}*{}={}\t".format(y, x, x*y), end=" ") #另一种写法,感觉更优雅,不限定数据类型
y += 1 #居然不支持++ !!!
print()
x += 1
3.字符串、列表、元组、字典
3.1 字符串
word = '字符串'
sentence = "这是一个句子。"
paragraph = """这是一个段落,
可以由多行组成"""
3.1.1 单引号和双引号如何选择?
1、包含单引号的字符串
假如你想定义一个字符串my_str,其值为: I’m a student,则可以采用如下方式,通过转义字符 \ 进
行定义。
my_str = 'I\'m a student'
也可以不使用转义字符,利用双引号直接进行定义。
my_str = "I'm a student"
2、包含双引号的字符串
假如你想定义一个字符串my_str,其值为: Jason said “I like you” ,则可以采用如下方式,通过转义字符 \ 进行定义。
my_str = "Jason said \"I like you\""
也可以不使用转义字符,利用单引号直接进行定义。
my_str = 'Jason said "I like you"'
3.1.2 转义字符
3.1.3 字符串的截取和连接
str='chengdu'
print(str) # 输出字符串
print(str[0:-1]) # 输出第一个到倒数第二个的所有字符
print(str[0]) # 输出字符串第一个字符
print(str[2:5]) # 输出从第三个开始到第五个的字符
print(str[2:]) # 输出从第三个开始后的所有字符
print(str * 2) # 输出字符串两次
print(str + '你好') # 连接字符串
print(str[:5]) # 输出第五个字母前的所有字符
print(str[0:7:2]) # [起始:终止:步长]
print('------------------------------')
print('hello\nchengdu') # 使用反斜杠(\)+n转义特殊字符
print(r'hello\npython') # 在字符串前面添加一个 r,表示原始字符串,不会发生转义
3.1.4 字符串的常见操作
序号 | 方法及描述 |
1 | capitalize() 将字符串的第一个字符转换为大写 |
2 | center(width, fifillchar) 返回一个指定的宽度 width 居中的字符串,fifillchar 为填充的字符,默认为空格。 |
3 | count(str, beg= 0,end=len(string)) 返回 str 在 string 里面出现的次数,如果 beg 或者 end指定则返回指定范围内 str 出现的次数 |
4 | bytes.decode(encoding=“utf-8”, errors=“strict”) Python3 中没有 decode 方法,但我们可以使用 bytes 对象的 decode() 方法来解码给定的 bytes 对象,这个 bytes 对象可以由str.encode() 来编码返回。 |
5 | encode(encoding=‘UTF-8’,errors=‘strict’) 以 encoding 指定的编码格式编码字符串,如果出错默认报一个ValueError 的异常,除非 errors 指定的是’ignore’或者’replace’ |
6 | endswith(suffiffiffix, beg=0, end=len(string)) 检查字符串是否以 obj 结束,如果beg 或者 end指定则检查指定的范围内是否以 obj 结束,如果是,返回 True,否则返回 False. |
7 | expandtabs(tabsize=8) 把字符串 string 中的 tab 符号转为空格,tab 符号默认的空格数是 |
8 | fifind(str, beg=0, end=len(string)) 检测 str 是否包含在字符串中,如果指定范围 beg 和 end,则检查是否包含在指定范围内,如果包含返回开始的索引值,否则返回-1 |
9 | index(str, beg=0, end=len(string)) 跟fifind()方法一样,只不过如果str不在字符串中会报一个异常. |
10 | isalnum() 如果字符串至少有一个字符并且所有字符都是字母或数字则返 回 True,否则返回False |
11 | isalpha() 如果字符串至少有一个字符并且所有字符都是字母则返回 True, 否则返回 False |
12 | isdigit() 如果字符串只包含数字则返回 True 否则返回 False… |
13 | islower() 如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写,则返回 True,否则返回 False |
14 | isnumeric() 如果字符串中只包含数字字符,则返回 True,否则返回 False |
15 | isspace() 如果字符串中只包含空白,则返回 True,否则返回 False. |
16 | istitle() 如果字符串是标题化的(见 title())则返回 True,否则返回 False |
17 | isupper() 如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是大写,则返回 True,否则返回 False |
18 | join(seq) 以指定字符串作为分隔符,将 seq 中所有的元素(的字符串表示)合并为一个新的字符串 |
19 | len(string) 返回字符串长度 |
20 | [ljust(width, fifillchar]) 返回一个原字符串左对齐,并使用 fifillchar 填充至长度 width 的新字符串,fifillchar 默认为空格。 |
21 | lower() 转换字符串中所有大写字符为小写. |
22 | lstrip() 截掉字符串左边的空格或指定字符。 |
23 | maketrans() 创建字符映射的转换表,对于接受两个参数的最简单的调用方式,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标。 |
24 | max(str) 返回字符串 str 中最大的字母。 |
25 | min(str) 返回字符串 str 中最小的字母。 |
26 | [replace(old, new , max]) 把 将字符串中的 str1 替换成 str2,如果 max 指定,则替换不超过 max 次。 |
27 | rfifind(str, beg=0,end=len(string)) 类似于 fifind()函数,不过是从右边开始查找. |
28 | rindex( str, beg=0, end=len(string)) 类似于 index(),不过是从右边开始. |
29 | [rjust(width, fifillchar]) 返回一个原字符串右对齐,并使用fifillchar(默认空格)填充至长度width 的新字符串 |
30 | rstrip() 删除字符串字符串末尾的空格. |
31 | split(str="", num=string.count(str)) num=string.count(str)) 以 str 为分隔符截取字符串,如果 num 有指定值,则仅截取 num+1 个子字符串 |
32 | [splitlines(keepends]) 按照行(’\r’, ‘\r\n’, \n’)分隔,返回一个包含各行作为元素的列表,如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符。 |
33 | startswith(substr, beg=0,end=len(string)) 检查字符串是否是以指定子字符串 substr 开头,是则返回 True,否则返回 False。如果beg 和 end 指定值,则在指定范围内检查。 |
34 | [strip(chars]) 在字符串上执行 lstrip()和 rstrip() |
35 | swapcase() 将字符串中大写转换为小写,小写转换为大写 |
36 | title() 返回"标题化"的字符串,就是说所有单词都是以大写开始,其余字母均为小写(见istitle()) |
37 | translate(table, deletechars="") 根据 str 给出的表(包含 256 个字符)转换 string 的字符, 要过滤掉的字符放到 deletechars 参数中 |
38 | upper() 转换字符串中的小写字母为大写 |
39 | zfifill (width) 返回长度为 width 的字符串,原字符串右对齐,前面填充0 |
40 | isdecimal() 检查字符串是否只包含十进制字符,如果是返回 true,否则返回 false。 |
3.2 列表
3.2.1 列表的定义与访问
- 列表的格式
变量A的类型为列表
namesList = ['xiaoWang','xiaoZhang','xiaoHua']
比C语言的数组强大的地方在于列表中的元素可以是不同类型的
testList = [1, 'a']
- 打印列表
demo:
namesList = ['xiaoWang','xiaoZhang','xiaoHua']
print(namesList[0])
print(namesList[1])
print(namesList[2])
- 列表的循环遍历
为了更有效率的输出列表的每个数据,可以使用循环来完成
demo:
namesList = ['xiaoWang','xiaoZhang','xiaoHua']
for name in namesList:
print(name)
3.2.3 常用操作
—操作名称— | 操作方法 | 举例 |
访问列表中的元素 | 通过下标直接访问 | print(list1[0]) |
列表的切片 | 使用[::] | list1[2:5:2] |
遍历列表 | 通过for循环 | for i in list1: print(i) |
【增】新增数据到列表 | 尾部 | 使用append |
【增】列表的追加 | 使用extend方法 | list1.extend(list2) |
【增】列表数据插入 | insert方法 | list1.insert(1,3) |
【删】列表的删除 | del:我们通过索引删除指定位置的元素。 remove:移除列表中指定值的第一个匹配值。如果没找到的话,会抛异常。 | del list1[0] list1.remove(1)注意两种方法的区别 |
【删】弹出列表尾部元素 | 使用pop | list1.pop() |
【改】更新列表中的数据 | 通过下标原地修改 | list1[0]=8 |
【查】列表成员关系 | in、notin | 2 in list1 |
列表的加法操作 | + | list3=list1+list2 |
【排】列表的排序 | sort方法 | list1.sort() |
【排】列表的反转 | reverse | list1.reverse() |
获取列表长度 | len() | |
获取列表元素最大值 | max() | |
获取列表元素最小值 | min() | |
其它类型对象转换成列表 | list() |
3.2.4 列表的嵌套
- 列表嵌套
类似while循环的嵌套,列表也是支持嵌套的
一个列表中的元素又是一个列表,那么这就是列表的嵌套
schoolNames = [['北京大学','清华大学'],
['南开大学','天津大学','天津师范大学'],
['山东大学','中国海洋大学']]
- 应用
一个学校,有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)
作业:
现有商品列表如下:
- products = [[“iphone”,6888],[“MacPro”,14800],[“小米6”,2499],[“Coffffee”,31],[“Book”,60],[“Nike”,699]],需打印出以下格式:
------ 商品列表 ------
0 iphone 6888
1 MacPro 14800
2 小米6 2499
3 Coffee 31
4 Book 60
5 Nike 699
products = [["iphone",6888],["MacPro",14800],["小米6",2499],["Coffffee",31],["Book",60],["Nike",699]]
i = 0
for prod in products:
print("{}\t{}\t{}".format(i, prod[0], prod[1]))
i += 1
- 根据上面的products列表写一个循环,不断询问用户想买什么,用户选择一个商品编号,就把对应的商品添加到购物车里,最终用户输入q退出时,打印购买的商品列表。
products = [["iphone", 6888], ["MacPro", 14800], ["小米6", 2499], ["Coffffee", 31], ["Book", 60], ["Nike", 699]]
car = []
select = -1
while select != "q":
select = input("请输入你要购买的商品编号 0-5, 或输入q退出: ")
try:
select = int(select)
if select >= 0 or select <= 5:
prod = products[select]
car.append(prod) #这里居然踩雷了!!用extend居然是一维列表/数组,导致下面无法做二维遍历
else:
continue
except:
if select == "q":
break
else:
continue
print("用户购物车清单如下")
print("-----------------")
for i in range(len(car)):
prod = list(car[i])
print("{}\t{}\t{}".format(i, prod[0], prod[1]))
3.3 元组
3.3.1 元组的定义与访问
- 创建空元组
tup1 = ()
- 元组的定义
tup1 = (50) # 不加逗号,类型为整型
print(type(tup1)) #输出<class 'int'>
tup1 = (50,) # 加逗号,类型为元组
print(type(tup1)) #输出<class 'tuple'>
- 元组的访问
tup1 = ('Google', 'baidu', 2000, 2020)
tup2 = (1, 2, 3, 4, 5, 6, 7 )
print ("tup1[0]: ", tup1[0])
print ("tup2[1:5]: ", tup2[1:5])
- 元组中的元素值是不允许修改的,但我们可以对元组进行连接组合,如下实例:
tup1 = (12, 34.56)
tup2 = ('abc', 'xyz')
# 以下修改元组元素操作是非法的。
# tup1[0] = 100
# 创建一个新的元组
tup3 = tup1 + tup2
print (tup3)
- 删除元组后,再次访问会报错
tup = ('Google', 'baidu', 2000, 2020)
print (tup)
del tup
print ("删除后的元组 tup : ")
print (tup)
3.3.2 常用操作:
操作名称 | 操作方法 | 举例 |
访问元组中的元素 | 通过下标直接访问 | print(tuple1[0]) |
遍历元组 | 通过for循环 | for i in tuple1: print(i) |
元组的切片 | 使用[: :] | tuple1[2:5:2] |
元组的加法操作 | + | tuple3 = tuple1 + tuple2 |
元组成员关系 | in | 2 in list1 |
得到重复元素数量 | count | tuple1.count(1) |
获取元组长度 | len() | |
获取元组元素最大值 | max() | |
获取元组元素最小值 | min() | |
其它类型对象转换成元组 | tuple() |
3.4 字典
3.4.1 字典的定义
变量info为字典类型:
info = {'name':'班长', 'id':100, 'sex':'f', 'address':'地球亚洲中国北京'}
说明:
- 字典和列表一样,也能够存储多个数据
- 列表中找某个元素时,是根据下标进行的
- 字典中找某个元素时,是根据’名字’(就是冒号:前面的那个值,例如上面代码中的’name’、‘id’、‘sex’)
- 字典的每个元素由2部分组成,键:值。例如 ‘name’:‘班长’ ,'name’为键,'班长’为值
3.4.2 根据键访问值
info = {'name':'吴彦祖','age':18}
print(info['age']) # 获取年龄
# print(info['sex']) # 获取不存在的key,会发生异常
print(info.get('sex')) # 获取不存在的key,获取到空的内容,不会出现异常
若访问不存在的键,则会报错:
info['sex']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'sex'
在我们不确定字典中是否存在某个键而又想获取其值时,可以使用get方法,还可以设置默认值:
>>> age = info.get('age')
>>> age #'age'键不存在,所以age为None
>>> type(age)
<type 'NoneType'>
>>> age = info.get('age', 18) # 若info中不存在'age'这个键,就返回默认值18
>>> age
18
3.4.3 常用操作:
操作名称 | 操作方法 | 举例 |
访问字典中的元素(1) | 通过key访问,key不存在会抛出异常 | print(dict1[“小明”]) |
访问字典中的元素(2) | 通过get方法,不存在返回None,不抛出异常 | print(dict1.get(“”小明)) |
遍历字典(1) | 通过for循环,只能获取key | for key in dict1: print(key, dict1[key]) |
遍历字典(2) | 配合items方法,获取key和val | for key, val in dict1.items(): print(key, val) |
直接获取所有key和value | 使用keys和values方法 | print(dict1.values()) print(dict1.keys()) |
修改val | 直接通过key修改 | dict1[‘小明’] = 2003 |
新增键值对 | 直接新增 | dict1[‘小李’] = 2005 |
字典元素的删除 | 通过key删除 | del dict1[‘小李’] |
字典元素的弹出 | 通过pop方法 | dict1.pop(“小李”) |
判断key是否存在 | in | “key” in dict1 |
合并字典 | update | dict1.update(dict2) |
把两个列表转为字典 | dict+zip方法 | dict(zip(list1,list2)) |
把一个嵌套列表转为字典 | dict方法 | dict2 = dict([[‘key1’, ‘value1’]]) |
清除字典内的元素 | clear方法 | dict1.clear() |
获取字典长度 | len() | |
获取最大的key | max() | |
获取最小的key | min() | |
其它类型对象转换成字典 | dict() | dict([(1, 2), (2, 3)]) |
3.5 集合
常用操作:
操作名称 | 操作方法 | 举例 |
遍历集合 | 通过for循环 | for i in set1: print(i) |
更新集合 | update方法 | set1.update(set2) |
向集合添加新元素 | add方法 | set1.add(5) |
移除集合中的元素 | remove方法 | set1.remove(5) |
弹出元素 | pop方法 | val = set1.pop() |
清除元素 | clear方法 | set1.clear() |
删除集合 | del | del set1 |
获取集合长度 | len() | |
获取最大的元素 | max() | |
获取最小的元素 | min() | |
其它类型对象转换成集合 | set() |
3.6小结
是否有序 | 是否可变类型 | |
列表[ ] | 有序 | 可变类型 |
元组( ) | 有序 | 不可变类型 |
字典{ } | 无序 | key不可变 val可变 |
集合{ } | 无序 | 可变类型(不重复) |
4.函数
4.1 函数的概念
如果在开发程序时,需要某块代码多次,但是为了提高编写的效率以及代码的重用,所以把具有独
立功能的代码块组织为一个小模块,这就是函数。
4.2 函数定义和调用
4.2.1 定义函数
定义函数的格式如下:
def 函数名():
代码
demo:
# 定义一个函数,能够完成打印信息的功能
def printInfo():
print '------------------------------------'
print ' 人生苦短,我用Python'
print '------------------------------------'
4.2.2 调用函数
定义了函数之后,就相当于有了一个具有某些功能的代码,想要让这些代码能够执行,需要调用它调用函数很简单的,通过函数名() 即可完成调用
demo:
# 定义完函数后,函数是不会自动执行的,需要调用它才可以
printInfo()
4.3 函数参数
4.3.1 定义带有参数的函数
示例如下:
def add2num(a, b):
c = a+b
print c
4.3.2 调用带有参数的函数
以调用上面的add2num(a, b)函数为例:
def add2num(a, b):
c = a+b
print c
add2num(11, 22) #调用带有参数的函数时,需要在小括号中,传递数据
调用带有参数函数的运行过程:
4.4 函数返回值
4.4.1 带有返回值的函数
想要在函数中把结果返回给调用者,需要在函数中使用return
如下示例:
def add2num(a, b):
c = a+b
return c
或者
def add2num(a, b):
return a+b
4.4.2 保存函数的返回值
在本小节刚开始的时候,说过的“买烟”的例子中,最后儿子给你烟时,你一定是从儿子手中接过来 对么,程序也是如此,如果一个函数返回了一个数据,那么想要用这个数据,那么就需要保存
保存函数的返回值示例如下:
#定义函数
def add2num(a, b):
return a+b
#调用函数,顺便保存函数的返回值
result = add2num(100,98)
#因为result已经保存了add2num的返回值,所以接下来就可以使用了
print result
4.4.3在python中我们可不可以返回多个值? (了解)
>>> def divid(a, b):
... shang = a//b
... yushu = a%b
... return shang, yushu
...
>>> sh, yu = divid(5, 2)
>>> sh
5
>>> yu
1
本质是利用了元组
课堂练习:
- 写一个打印一条横线的函数。(提示:横线是若干个“-”组成)
- 写一个函数,可以通过输入的参数,打印出自定义行数的横线。(提示:调用上面的函数)
- 写一个函数求三个数的和
- 写一个函数求三个数的平均值(提示:调用上面的函数)
【建议每题5分钟以内】
参考代码1-2:
# 打印一条横线
def printOneLine():
print("-"*30)
# 打印多条横线
def printNumLine(num):
i=0
# 因为printOneLine函数已经完成了打印横线的功能,
# 只需要多次调用此函数即可
while i<num:
printOneLine()
i+=1
printNumLine(3)
参考代码3-4:
# 求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.5 局部变量和全局变量
4.5.1 局部变量
什么是局部变量
如下图所示:
小总结
- 局部变量,就是在函数内部定义的变量
- 不同的函数,可以定义相同的名字的局部变量,但是各用个的不会产生影响
- 局部变量的作用,为了临时保存数据需要在函数中定义变量来进行存储,这就是它的作用
4.5.2 全局变量
什么是全局变量
如果一个变量,既能在一个函数中使用,也能在其他的函数中使用,这样的变量就是 全局变量
demo如下:
# 定义全局变量
a = 100
def test1():
print(a)
def test2():
print(a)
# 调用函数
test1()
test2()
全局变量和局部变量名字相同问题
看如下代码:
修改全局变量
既然全局变量,就是能够在所以的函数中进行使用,那么可否进行修改呢?
代码如下:
总结:
- 在函数外边定义的变量叫做 全局变量
- 全局变量能够在所有的函数中进行访问
- 如果在函数中修改全局变量,那么就需要使用 global 进行声明,否则出错
- 如果全局变量的名字和局部变量的名字相同,那么使用的是局部变量的,小技巧 强龙不压地头蛇
4.6 函数使用注意事项
4.6.1.自定义函数
<1>无参数、无返回值
def 函数名():
语句
<2>无参数、有返回值
def 函数名():
语句
return 需要返回的数值
注意:
- 一个函数到底有没有返回值,就看有没有return,因为只有return才可以返回数据
- 在开发中往往根据需求来设计函数需不需要返回值
- 函数中,可以有多个return语句,但是只要执行到一个return语句,那么就意味着这个函数的调用完成
<3>有参数、无返回值
def 函数名(形参列表):
语句
注意:
- 在调用函数时,如果需要把一些数据一起传递过去,被调用函数就需要用参数来接收
- 参数列表中变量的个数根据实际传递的数据的多少来确定
<4>有参数、有返回值
def 函数名(形参列表):
语句
return 需要返回的数值
<5>函数名不能重复
4.6.2.调用函数
<1>调用的方式为:**
函数名([实参列表])
<2>调用时,到底写不写 实参
如果调用的函数 在定义时有形参,那么在调用的时候就应该传递参数
<3>调用时,实参的个数和先后顺序应该和定义函数中要求的一致
<4>如果调用的函数有返回值,那么就可以用一个变量来进行保存这个值
4.6.3.作用域
<1>在一个函数中定义的变量,只能在本函数中用(局部变量)
**<2>在函数外定义的变量,可以在所有的函数中使用(全局变量) **
5.文件操作
文件,就是把一些数据存放起来,可以让程序下一次执行的时候直接使用,而不必重新制作一份,省时省力。
5.1 文件打开与关闭
5.1.1 打开文件
在python,使用open函数,可以打开一个已经存在的文件,或者创建一个新文件
open(文件名,访问模式)
示例如下:
f = open('test.txt', 'w')
说明:
访问模式 | 说明 |
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
w | 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
w+ | 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
5.1.2 关闭文件
close( )
示例如下:
# 新建一个文件,文件名为:test.txt
f = open('test.txt', 'w')
# 关闭这个文件
f.close()
5.2 文件读写
5.2.1 写数据(write)
使用write()可以完成向文件写入数据
demo:
f = open('test.txt', 'w')
f.write('hello world, i am here!')
f.close()
注意:
- 如果文件不存在那么创建,如果存在那么就先清空,然后写入数据
5.2.2 读数据(read)
使用read(num)可以从文件中读取数据,num表示要从文件中读取的数据的长度(单位是字节),如果
没有传入num,那么就表示读取文件中所有的数据
demo:
f = open('test.txt', 'r')
content = f.read(5)
print(content)
print("-"*30)
content = f.read()
print(content)
f.close()
注意:
- 如果open是打开一个文件,那么可以不用写打开的模式,即只写 open(‘test.txt’)
- 如果使用读了多次,那么后面读取的数据是从上次读完后的位置开始的
5.2.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()
5.2.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 文件的相关操作
有些时候,需要对文件进行重命名、删除等一些操作,python的os模块中都有这么功能
5.3.1 文件重命名
os模块中的rename()可以完成对文件的重命名操作
rename(需要修改的文件名, 新的文件名)
import os
os.rename("毕业论文.txt", "毕业论文-最终版.txt")
5.3.2 删除文件
os模块中的remove()可以完成对文件的删除操作
remove(待删除的文件名)
import os
os.remove("毕业论文.txt")
5.3.3 创建文件夹
import os
os.mkdir("张三")
5.3.4 获取当前目录
import os
os.getcwd()
5.3.5 改变默认目录
import os
os.chdir("../")
5.3.6 获取目录列表
import os
os.listdir("./")
5.3.7 删除文件夹
import os
os.rmdir("张三")
6.错误与异常
6.1 异常简介
看如下示例:
print '-----test--1---'
open('123.txt','r')
print '-----test--2---'
运行结果:
说明:
打开一个不存在的文件123.txt,当找不到123.txt 文件时,就会抛出给我们一个IOError类型的错误,No such fifile or directory:123.txt (没有123.txt这样的文件或目录)
异常:
当Python检测到一个错误时,解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的"异常"
6.2 捕获异常 try…except…
看如下示例:
try:
print('-----test--1---')
open('123.txt','r')
print('-----test--2---')
except IOError:
pass
说明:
- 此程序看不到任何错误,因为用except 捕获到了IOError异常,并添加了处理的方法
- pass 表示实现了相应的实现,但什么也不做;如果把pass改为print语句,那么就会输出其他信息
小总结:
- 把可能出现问题的代码,放在try中
- 把处理异常的代码,放在except中
6.3 except捕获多个异常
看如下示例:
try:
print num
except IOError:
print('产生错误了')
想一想:
上例程序,已经使用except来捕获异常了,为什么还会看到错误的信息提示?
答:
except捕获的错误类型是IOError,而此时程序产生的异常为 NameError ,所以except没有生效
修改后的代码为:
try:
print num
except NameError:
print('产生错误了')
实际开发中,捕获多个异常的方式,如下:
#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 后,并使用元组的方式仅进行存储
6.4 获取异常的信息描述
6.5 捕获所有异常
6.6 try…fifinally…
try…fifinally…语句用来表达这样的情况:
在程序中,如果一个段代码必须要执行,即无论异常是否产生都要执行,那么此时就需要使用fifinally。 比如文件关闭,释放锁,把数据库连接返还给连接池等
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异常被触发,程序退出。但是在程序退出之前,fifinally从句仍然被执行,把文件关闭。
作业:
- 应用文件操作的相关知识,通过Python新建一个文件gushi.txt,选择一首古诗写入文件中
- 另外写一个函数,读取指定文件gushi.txt,将内容复制到copy.txt中,并在控制台输出“复制完毕”。
- 提示:分别定义两个函数,完成读文件和写文件的操作
尽可能完善代码,添加异常处理。
def createGushi():
f = open("gushi.txt", "w")
try:
f.write("Beautiful is better than ugly.\n")
f.write("Explicit is better than implicit.\n")
f.write("Simple is better than complex.\n")
except Exception as ex:
print(ex)
finally:
f.close()
print("创建古诗完毕!")
def copygushi():
f1 = open("gushi.txt", "r")
f2 = open("copy.txt", "w")
try:
f2.write(f1.read())
except Exception as ex:
print(ex)
finally:
f1.close()
f2.close()
print("复制古诗完毕!")
createGushi()
copygushi()