总注:
- 函数用法是
函数(参数如列表名)
,方法用法是数据.方法名(参数or空)
- pip 安装中的权限的问题:
sudo pip3 install packagename
代表进行全局安装,安装后全局可用。如果是信任的安装包可用使用该命令进行安装。
pip3 install --user packagename
代表仅该用户的安装,安装后仅该用户可用。处于安全考虑,尽量使用该命令进行安装。 -
if \_\_name\_\_ == '\_\_main\_\_':
下的代码只有在文件作为脚本直接执行才会被执行, import的时候不会被执行。
- 当运行模块被执行的时候,__name__等于文件名(包含了后缀.py);如果import到其他模块中,则__name__等于模块名称(不包含后缀.py)。而“__main__”等于当前执行文件的名称(包含了后缀.py)。进而当模块被直接执行时,__name__ == '__main__'结果为真。
- sys.argv得到的是输入的所有参数,即命令行Terminal中输入的
python Cplexpythonapilpex1.py -r
中python后面的部分,以列表形式保存,print(sys.argv)
输出出来结果是:['Cplexpythonapilpex1.py', '-r']
- 例:
if __name__ == "__main__":
if len(sys.argv) != 2 or sys.argv[1] not in ["-r", "-c", "-n"]:
print("Usage: lpex1.py -X")
print(" where X is one of the following options:")
print(" r generate problem by row")
print(" c generate problem by column")
print(" n generate problem by nonzero")
print(" Exiting...")
sys.exit(-1)
lpex1(sys.argv[1][1])
- 补Anaconda安装中的问题:
anaconda在windows中安装时要注意后面如果想用cmd命令行来进行操作使用conda
命令的话,需要将Anaconda、Anaconda/Scripts、Anaconda/Library/bin三个目录加入path中,具体path的加入方法为:此电脑->右键选择属性->高级系统设置->环境变量->系统变量->path
Chapter1 起步
1. python自带在终端窗口运行的解释器
- 只要代码清单中包含三个尖括号">>>",就意味着输出来自终端会话。
- Terminal中运行的命令:python 或者 python3
- Terminal中退出方法:Ctrl+D 或者 exit()
2. print("hello world!")
- 作用:如果它能运行,那么任何python程序都可以。
3. 在不同系统中搭建python编程环境
-
检查是否安装python以及版本->安装编辑器(Geany)->创建python文件hello world->运行、排除故障等
- Python命名规定:最好用小写字母,空格用'_'代替。
- Python命名规定:最好用小写字母,空格用'_'代替。
Chapter2 变量和简单数据类型
1. 运行hello_world.py中发生的情况
-
.py -> 说明是python程序,因此编辑器将使用Python解释器来运行。
-
编辑器以各种方式突出程序不同部分->语法突出
2. 变量
- 每个变量都存储了一个值——与变量相关联的信息
- 在程序中可随时修改变量的值,Python将始终记录变量的最新值。
有关变量的规则:
- 变量名只能以字母或下划线打头,只能包含字母、数字、下划线,不能含空格。(目前应使用小写的变量名,大写也没错,但是最好避免)
- 不要将Python关键字和函数名以及保留做特殊用途的单词用作变量名。
- 变量名应既简短又具有描述性。
- 慎用字母'l'和'o',容易被和数字1,0混淆。
3. 字符串——一系列字符
Python中用引号括起的都是字符串(单引号、双引号),这种灵活性可以让你在字符串中包含 引号 和 撇号。
- 修改字符串的大小写——"方法":Python可对 数据 进行的操作, 后跟括号以提供额外的信息。
name="ada lovelace"
print(name.title())#首字母大写
print(name.upper())#全大写
print(name.lower())#全小写
#句点'.'让Python对变量name执行方法制定的操作,title()是方法用来 首字母大写显示单词,lower()小写,upper()大写。
- 合并(拼接)字符串
Python使用加号"+"来合并字符串,这种方法称为"拼接"。
- 使用制表符'\t'和换行符'\n'来添加空白
空白:泛指任何非打印字符
制表符'\t',换行符'\n'
- 删除空白——可以删除字符串开头和末尾的空白
rstrip()删除末尾空格,
lstrip()删除开头空格,
strip()删除两边空格。
这种是‘暂时’的删除,要永久删除要对变量重新赋值!
favorite_language=' python '
print(favorite_language.rstrip()+'|')#删除末尾空格
print(favorite_language.lstrip()+'|')#删除开头空格
print(favorite_language.strip()+'|')#删除两边空格
- 使用字符串时避免语法错误
- 看报错,“语法突出”功能可以帮助快速找出语法错误。
- Python 2中的print语句无需加括号
4. 数字
- 整数
Python中可对整数进行如下运算:
+-*/ -> 加减乘除
乘方 -> **
运算次序 -> ()来改变
空格' ' -> 不影响表达式,只是帮助阅读 - 浮点数--带小数点的数字,小数点可出现在数字的任何位置!
- 大部分使用时没问题
- 注意:结果包含的小数位数可能是不确定的,如:
>>> 0.2+0.1
0.30000000000000004
所有语言都存在这种问题,暂时忽略多余的小数位即可。
- 使用函数str()避免类型错误
- 为防止类型错误(如print()函数里面需要是字符串变量),需要显式地调用函数str()来将非字符串值表示为字符串。
- Python 2中的整数
- 计算结果的小数部分直接删除(不是四舍五入),因此可以确保至少将一个操作数设置为浮点数结果就可以为浮点数了。
5. 注释--使用自然语言说明程序
- 编写注释
- "#"后面的部分被Python解释器自动忽略
- 该编写什么样的注释
- 注释的主要目的--阐述代码要做什么,以及如何做的
- 编写有意义的、描述性的、清晰、简洁的注释。
6. Python之禅
Beautiful is better than ugly.
Simple is better than complex.
Complex is better than complicated.
Readibility counts.
There should be one-- and preferably only one --obvious way to do it.
Now is better than never.
漂亮、优雅、简单、正确性!
Chapter3 列表简介
1. 列表--有序集合
- 列表由一系列按特定顺序排列的元素组成。
- 可以将任何东西加入列表中,元素之间可以没有任何关系。
- 可以给列表一个表示复数的名称(e.g. dogs)
Python中的表示:
[] | 列表 |
---|---|
, | 分隔元素 |
打印列表的内部表示包括"[]" |
- 访问列表元素
- 格式 ->
列表名称[元素索引]
- 输出时可以对任何列表元素调用字符串的"方法"如title()等。
- 索引从0开始(小心 差一错误)
- 索引为复数 -> 倒数第几个元素 -- 可以用来在不知道列表长度的情况下来访问倒数第几个的元素
- 使用列表中各个值
- 像使用其他变量一样
2. 修改、添加和删除元素
- 大多数创建的列表--动态的 -> 随程序运行增、删、改元素
- 修改列表元素
语法类似访问列表--指定列表名+元素索引,再指定新值 - 在列表添加元素
(1) 列表末尾添加元素 ->append()
- 方法append()将元素添加到列表末尾,不影响其他所有元素。
- 方法append()用来动态创建列表非常常见、容易,可以先创建空列表,再往里面添加元素,因为很多时候要等程序运行后才知道用户要在程序中存储哪些数据。
(2) 列表中插入元素(在中间任何位置插入) ->insert(i,'')
- 方法insert()可在列表的任何位置添加新元素,要指定新元素的索引和值。
注:insert()的位置为索引位置之前,如0就是在第一个元素之前增加一个元素(即成为第索引位置的元素)。
(3) 列表中删除元素
可以根据 位置 或 值 来删除列表中元素
1-使用del语句删除元素 ->del 列表名[索引]
如果知道删除的元素在列表中的位置,可使用del语句
2-使用方法pop()删除元素 -> 删除末尾元素,接着使用它
类似于弹出栈顶元素,并接着使用其值
3-弹出列表中任何位置的元素 -> pop(i)
注意:使用pop()后,被弹出元素不再在列表里了!
4-根据值删除元素->remove()
,只删除第一个指定值元素
不知道从列表中删除的值所处位置,只知道要删除的值,可以使用方法remove()。
remove()从列表中删除元素时,也可以接着使用它的值。
3. 组织列表
- 创建的列表中,元素排列顺序常常是无法预测的,常需要以特定顺序呈现信息--需要组织列表。
- 使用方法sort()对列表进行永久性排序
- 按照字母表顺序排列,永久性改变
- 如要按照字母表反序--将方法sort()的传递参数reverse=True
- 使用函数sorted()对列表进行临时排序
- 保留原顺序,以特定顺序呈现。
- 反序--向函数sorted(列表名,reverse=True/False等传递参数)传递参数reverse=True
注意:有大写字母时,按字母顺序排列列表复杂一些,有多种解读大写字母的方式,要选定准确的排列顺序。
- 反转排列列表顺序 -> 方法reverse()--永久性改变
- 确定列表长度 -> 函数len(列表名)(从1开始,应该无差一错误)
4. 使用列表时避免索引错误
- 防止 差一错误
- 防止 out of range
- 倒数的元素可以用复数索引如-1
- 找不到解决方法时 -> 将列表或长度打印出来看看列表长啥样
Chapter4 操作列表
注意:
- 这里的索引是用中括号"[]"括起来的,不是matlab中的小括号!!!
- 对列表的每个元素都采取一个或者一系列相同的措施,高效处理任何长度的列表。
1. 遍历 整个列表
需要对列表中每个元素都进行相同的操作,可使用Python中 for循环。
- 深入地研究循环
- for循环中,存储列表中每个值的临时变量可指定任何名称,但是选择描述单个列表元素的 有意义的名称 大有帮助,有助于理解代码。
- 在for循环中执行更多操作
- 每个缩进的代码行都是循环的一部分。因此,可以对列表中的每个值执行任意次数的操作。
- 在for循环结束后执行一些操作
- 在for循环后面,不缩进的代码只执行一次,不会重复执行。
2. 避免缩进错误
Python通过使用缩进让代码变得易读。
- 忘记缩进--会提示错误
- 将紧跟在for语句后面的代码行缩进,可以消除。
- 忘记缩进额外的代码行--逻辑错误 语法可能正确
- 循环中执行多任务时忘记缩进一部分代码。
- 预期对每个元素执行一次,结果却只执行了一次--可能需要缩进
- 不必要的缩进--Python会指出
- 循环后不必要的缩进--逻辑错误
- 不小心缩进了循环结束后执行的代码--会对每个元素重复执行
- 遗漏冒号
- 冒号告诉Python下一行是循环第一行。
- 难以发现,因为在意料之外。
3. 创建数字列表
- 列表非常适合存储数字集合,而Python也提供了很多工具帮助高速处理数字列表。
- 使用函数
range(开始值,结束值(,步长))
- 从第一个数开始,到达指定的第二个值停止(其实是到小于第二个的最后一个,所以输出不包括第二个值),第三个值可选择输入,代表步长。
- 使用range()创建数字列表
- 将range()作为list()的参数,函数list()将range()的结果直接转换成列表。
- 对数字列表进行简单的统计计算--max(),min(),sum()
- 列表解析--将for循环和创建新元素的代码合并成一行,并自动附加新元素 ->
列表名=[表达式 for循环]
- 只需一行代码完成squares中的三四行的任务
- for循环不加冒号
例:
squares=[value**2 for value in range(1,10)]
print(squares)
4. 使用列表的一部分
- 处理列表的部分元素--Python称为切片
- 切片 --
列表名[起始:终止+1],起始终止可缺省, 可负数
- 创建切片,指定第一个元素索引和最后一个元素索引加1(索引从0开始)
- 遍历切片--for循环中使用切片
- 复制列表--用 切片!省略起始和终止索引[:], 不能直接赋值!
注意:如果直接将列表赋值,相当于创建了一个关联,两个变量起始指向同一个列表!
- 用切片复制相当于建立了一个副本。
5. 元组 -- 使用 圆括号(), 可以使用索引访问其元素
- 不能修改的值 -- 不可变的
- 不可变的列表 -- 元组
- 列表 -> 值可以修改
元组 -> 值不能修改 - 修改元组元素的值 -- Python会报错!!!
- 定义元组、遍历元组--类似定义、遍历列表,用for循环即可
- 修改元组变量 -- 只能重新定义整个元组
- 因为给元组变量赋值是合法的,改变其元素值是不合法的!
6. 设置代码格式
- 格式设置指南
Python改进提案(PEP) PEP8--提供了代码格式设置指南 - 缩进--影响运行!
每级缩进使用4个空格
制表符和空格尽量不要混用,容易造成问题 - 行长
建议每行不超过80个字符,注释行不超过72字符 - 空行--不影响运行
将程序不同部分分开可使用空行。
空行不影响运行,缩进影响。 - 其他格式设置指南--未完待续
Chapter5 if语句 (和for循环一样,有冒号!!!)
-
编程时常需要检查一系列条件,据此决定采取什么措施。
-
Python中if语句能检查程序的当前状态,并据此采取相应的措施。
1. 简单示例
cars=['bmw','audi','toyota','subaru']
for car in cars:
if car=='bmw':
print(car.upper())
else:
print(car.title())
2. 条件测试(也称 布尔表达式)
- 每条if语句的核心都是一个值为True或False的表达式,这种表达式被称为 条件测试。Python根据条件测试的值为T或F来决定是否执行if语句中的代码。
- 值为True -> 执行
值为False -> 忽略,不执行
- 检查是否相等(相等运算符==)
大多数条件测试将一个变量的当前值同特定值比较。
一个等号= -> 陈述
两个等号== -> 发问 - 检查是否相等时不考虑大小写--用方法lower()全部改为小写
Python检查是否相等时 区分大小写!!! - 检查是否不相等(不相等!=)
大部分程序--检查是否相等
有时候--检查是否不等效率高 - 比较数字--可包含各种数学比较
print(1==1.0)
结果:True
- 检查多个条件--关键字 and 和 or
(1) 使用and检查多个条件
- 只有每个条件测试都通过--True, 否则--False。
- 为改善可读性,可以把每个条件测试都放在一对括号里。
(2)使用or检查多个条件 - 至少一个满足--True, 否则--False。
- 检查特定值是否在列表中--关键字 in (元素 in 列表)
- 补注in用法不但可以
元素 in 列表/元组
,也可以是字符串 in 字符串
,即后一个字符串中是否包含前一个字符串
- 检查特定值是否不包含在列表中--关键字 not in
- 布尔表达式--条件测试的别名
布尔表达式结果要么True要么False,常用来记录条件。
3. if语句(冒号!!!)
- 简单if语句
if conditional_test:
do something
缩进作用与for循环中相同。
通过测试--执行所有缩进行;否则--忽略。
- if-else
True->执行一个,False->执行另一个 - if-elif-else -- 检查超过两个的情形
- 使用多个elif代码块
- 省略else代码块
- Python不要求if-elif结构必须要有else代码块,有些时候elif更清晰。
- 注意:else是包罗万象的语句,只要不满足任何if或elif就会执行,可能引入无效或者恶意数据!!!
- 测试多个条件
- 有时要测试所有条件,可以使用一系列不包含elif和else的代码块。
4. 使用if语句处理列表
- 检查特殊元素
- 确定列表非空
之前--假设列表至少一个元素。
其实,for循环前检查列表非空很重要。
if 列表名:#列表非空时返回True,列表空时返回False
- 使用多个列表 -- 用好关键字in, 理清楚逻辑关系
for requested_topping in requested_toppings:
if requested_topping in available_toppings:
print('Adding'+requested_topping+'.')
else:
print('Sorry, we do not have'+requested_topping+'.')
5. 设置if语句的格式
PEP8 提供的建议:
在比较运算符如==,>=,<=,!=等两边各添加一个空格。
Chapter6 字典--花括号"{}"
- 注意:用的是花括号"{}"
- 动态结构,能够将相关信息关联起来,可存储的信息量几乎不受限制,可以高效模拟现实世界中的情形。
1. 简单示例
alien_0={'color':'green','points':5}
print(alien_0['color'])
print(alien_0['point'])
- 使用字典
- 字典--一系列 键-值 对。花括号
{键:值,键:值,键:值,...}
- 每个键都与一个值相关联,可以使用键来访问与之相关联的值。
- 键与值之间--冒号":"分隔
键-值对之间--逗号","分隔
(1) 访问字典中的值
获取与键相关联的值->字典名[键名]
(2) 添加键-值对 - 语法格式:
字典名[键]=值
-
注意:Python不关心键-值对的添加顺序,只关心关联关系!!!
(3) 先创建一个空字典
alien_0={}
(4) 修改字典中的值
字典名[键]=新值
(5) 删除键-值对 - 使用del语句
del 字典名[键]
注意:del删除为永久删除!
(6) 由类似对象组成的字典 - 之前是字典存同一对象的不同信息,也可以用字典存储多对象的同一信息。
- 多行时可以用回车,下一行要tab缩进!!!
3. 遍历字典
- Python支持对字典遍历,可以遍历所有 键-值对、键、值。
- 遍历字典中所有键-值对
- for循环可声明两个变量,用于存储键-值对中键和值。对于这两个变量可以使用任何名称。
- for语句第二部分包含字典名和方法items(),它返回一个键-值对列表。
for key,value in 字典名.items():
user_0={
'username':'efermi',
'first':'enrico',
'last':'fermi',
}
for key,value in user_0.items():
print('\nKey:'+key)
print('Value:'+value)
- 遍历字典中所有键--方法keys()
- 在不需要使用字典中的值时,方法keys()很有用。
for name in favorite_languages.keys():
提取字典favorite_languages中所有的键并依次存储到name里面。 - 遍历字典时会默认遍历所有的键,因此
for name in favorite_languages.keys():
<==>for name in favorite_languages:
,只是如果显式使用方法keys()更容易理解。 - 在循环中,可以使用当前键来访问与之相关联的值。
- 可以用keys()来确认是否有这个键,用
if 键 not in 字典.keys()
即可。 - keys()的实质:返回一个列表,包含字典中所有的键。
- 按顺序遍历字典中的所有键
字典->记录键和值的关联关系,但是获取字典元素时,获取的顺序是不可预测的。
以特定的顺序返回元素->for循环中对返回的键进行排序(使用sorted()来获得按特定顺序排列的建列表的副本)。 - 遍历字典中的所有值--方法values()
- 如果感兴趣的主要是字典包含的值,可使用方法values(),返回值列表。没考虑是否重复
- 如果要剔除重复项--使用集合:
set(列表)
- set()类似于列表,但是每个元素必须独一无二,如:
for language in set(favorite_languages.values()):
4. 嵌套
- 有时候需要把字典存储在列表中,或者把列表存储作为值在字典中,称为嵌套。
- 字典列表
- 经常需要在列表中包含大量的字典,而其中每个字典都包含特定对象的众多信息。
如:
alien_0={'color':'green','points':5}
alien_1={'color':'green','points':5}
alien_2={'color':'green','points':5}
aliens=[alien_0, alien_1, alien_2]
print(aliens)
-
字典中存储列表
将列表存储在字典中,如:
pizza={
'crust':'thick',
'toppings':['mushrooms','extra cheese'],
}
- 每当需要在字典中将一个键关联到多个值时,都可以在字典中嵌套列表。
- 注意:列表和字典的嵌套层级不应太多。如果嵌套层级比前面示例多得多,很可能有更简单的解决方案。
- 字典中存储字典
- 这样做代码会很快复杂起来。
- 存储的字典的结构尽量相同,这样处理起来更容易,虽然python并未对此做强制要求。
Chapter7 用户输入和while循环
- 大多数程序->旨在解决最终用户的问题,为此通常需要从用户那里获得一些信息。
- 接受用户输入并能对其进行处理--input()
- 让程序不断运行--while循环
- 获取用户输入并控制程序运行的时间--编写交互式程序
1. 函数input()的工作原理
- input()让程序暂停运行,等待用户输入文本。获取用户输入后,Python将其存储在一个变量中,方便你使用。
- 函数input()接受一个参数:向用户显示的提示或说明
- 注意:sublime text不能运行提示用户输入的程序。只能用它编写,在终端运行。
- 例:
message=input("Tell me something, and I will repeat it back to you: ")
print(message)
Terminal:
python Chapter7.py
Tell me something, and I will repeat it back to you: ooooo
ooooo
- 编写清晰的程序
- 使用函数input()时,提示应清晰、易于明白。
- 提示的末尾(一般是冒号)后面最好包含一个空格来方便用户区分开提示和用户输入。
- 提示可能超过一行--可以将提示存储在一个变量中,再将变量传递给函数input(),这样input()语句会更加清晰。可以使用运算符+=在变量末尾附加字符串。
prompt="if you tell us who you are, we can personalize the message you see."
prompt+="\n What is your first name?"
name=input(prompt)
print("\nHello, "+name+'!')
Terminal:
python Chapter7.py
if you tell us who you are, we can personalize the message you see.
What is your first name?ooo
Hello, ooo!
- 使用int()获取数值输入
- 使用input()时,Python将用户输入解释为字符串!
- 可使用函数int(字符串)让Python将输入视为数值。
- 将数值输入用于计算和比较前,务必转换为数值表示!
- 求模运算符--%
- 求模运算符%将两数相除返回余数
- 不会指出倍数
- Python2.7中获取输入
- raw_input()对应Python3中的input()
- input()将用户输入解读为Python代码尝试运行
2. while循环简介
while循环--不断运行,知道指定条件不满足为止。
- 使用while循环--注意冒号
- 可以用来数数
- while 条件测试:
执行代码
- 让用户选择何时退出
- while 条件判断
- 有时条件中的用户输入的值要提前定义初始值方便第一次的运行
prompt="\nTell me something, and I will repeat it back to you: "
prompt+="\nEnter 'quit' to end the program."
message=''
while message != 'quit':
message=input(prompt)
if prompt != 'quit':
print(message)
Terminal:
Tell me something, and I will repeat it back to you:
Enter 'quit' to end the program.ooo
ooo
Tell me something, and I will repeat it back to you:
Enter 'quit' to end the program.kkk
kkk
Tell me something, and I will repeat it back to you:
Enter 'quit' to end the program.quit
- 使用标志
- 标志:很多条件都满足才继续运行的程序中,可以定义一个变量,用于判断整个程序是否处于活动状态,该变量称为标志。
- 简化了while语句,语句中不用做比较,相关逻辑由程序其他部分处理。
- 使用break退出循环
- 要立即退出while循环,不再运行循环中余下代码,也不管条件测试结果如何,可以使用break语句。
- 以while True打头的循环将不断运行,直到遇到break语句。
- 注意:Python中所有循环都可以使用break语句,如for和while等。
- 在循环中使用continue
- continue循环:忽略这次循环余下的代码,并返回到循环开头,并根据条件测试结果决定是否据需执行循环。
- 避免无限循环
- 每个while循环必须要有停止运行的途径。
- 陷入无限循环时:ctrl+C或者关闭显示程序输出的终端窗口。
- 避免编写无限循环--要对每个while循环测试!
- 注意:有的编辑器如sublime text内嵌了输出窗口,难以结束无限循环,要关闭编辑器来停止。
3. 使用while循环处理列表和字典
- 之前--每次只处理已向用户信息:获取用户输入,再对其输入应答;循环再次运行时,获得另一个输入并作出响应。
- 要记录大量的用户和信息--需要在while循环中使用列表和字典。
- for循环是一种遍历列表的有效方式,但在for循环中不应修改列表,否则将导致Python难以跟踪其中的元素。
- 遍历列表的同时对其进行修改 -> 使用while循环
- 在列表之间移动元素
用方法pop()从一个列表中删除,用current存储其值,再用方法append()(或者insert(i)其实也可以啊)把它加入到另一个列表中。
例:
unconfirmed_users=['alice','brian','candace']
confirmed_users=[]
while unconfirmed_users:
current_user=unconfirmed_users.pop()
print("Verifying user: "+current_user.title())
confirmed_users.append(current_user)
print("\nThe following users have been confirmed: ")
for confirmed_user in confirmed_users:
print(confirmed_user.title())
输出:
Verifying user: Candace
Verifying user: Brian
Verifying user: Alice
The following users have been confirmed:
Candace
Brian
Alice
- 删除包含特定值的所有列表元素
使用方法remove删除列表中的特定值,但是remove只能删除掉一个,要删除掉所有特定值的元素的方法--使用好while和in。
while 不想要的值 in 列表:
列表.remove(不想要的值)
例:
pets=['dog','cat','dog','goldfish','cat','rabbit','cat']
print(pets)
while 'cat' in pets:
pets.remove('cat')
print(pets)
输出:
['dog', 'cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat']
['dog', 'dog', 'goldfish', 'rabbit']
- 使用用户输入来填充字典
- 字典中添加键-值对:
字典名[新键]=新值
while 标志:
新键=input("新键输入提示")
新值=input("新值输入提示")
字典名[新键]=新值
标志的改变代码块
其他操作
我的问题:对重名的用户未处理,还可以进一步改进!
Chapter8 函数
- 函数--带名字的代码块,用于完成具体的工作。
- 要执行特定任务--调用该函数。
- 让程序的编写、阅读、测试、修复更加容易。
1. 定义函数--关键字def
def 函数名(完成任务需要的参数):
"""文档字符串(注释), 描述函数是做什么的"""
函数体(缩进部分)
- def--告诉Python要定义函数,并指出后面的函数名。
- 括号里是完成任务需要的信息,即使不需要也要加空括号,不能省略!
-
调用函数--依次指定函数名和括号括起来的必要的信息。
注意:def后面有冒号
- 向函数传递信息
最简单的例子:
def greet_user(username):#username是形参
"""显示简单的问候语"""
print("Hello, "+username.title()+"!")
greet_user('jessi')#jessi是实参
greet_user('sarah')
输出:
Hello, Jessi!
Hello, Sarah!
- 实参和形参
函数greet_user(username)中,
- username是形参--函数完成工作所需的信息
- greet_user('jessi')中的'jessi'是实参--调用函数时传递给函数的信息
- 在greet_user('jessi')中,将实参'jessi'传递给了函数greet_user(),值被储存在形参username中。
2. 传递实参
- 函数定义中可能包含多个形参,因此函数调用中也可能包含多个实参。
向函数传递参数的方式: - 位置实参实参的顺序与形参的顺序相同
- 关键字实参每个实参都由变量名和值组成
- 使用列表和字典
-
位置实参
调用函数时,Python必须将调用中的每个实参关联到函数定义中的一个形参
位置实参:最简单的关联方式--基于实参的顺序关联
- 调用函数多次--效率极高的工作方式。
- 可以根据需要按顺序使用任意数量的位置实参。
- 位置实参的顺序很重要。
- 关键字实参--传递给函数的名称-值对
- 直接在实参中将名称和值关联起来了,即明确使出了各个实参对应的形参。
- 关键字实参的顺序无关紧要(因为Python知道各个值对应哪个形参)。
- 注意:使用关键字实参时,务必准确地指定函数定义中的形参名。
- 默认值
- 可给每个形参指定默认值。
- 给形参提供了实参时-使用指定值;没提供实参时-使用形参默认值。
- 注意:要修改形参的排列顺序,让有默认值的在最后,否则Python会认为给的实参是位置实参!
-
显式地给有默认值的形参提供实参时,Python将忽略默认值。
1&2&3例:
def describe_pet(pet_name, animal_type='dog'):
"""显示宠物的信息"""
print("\nI have a "+animal_type+".")
print("My "+animal_type+"'s name is "+pet_name.title()+".")
describe_pet('hamster', 'harry')#顺序实参
describe_pet(animal_type='hamster', pet_name='harry')#关键字实参
describe_pet(pet_name='willie')#默认值
#describe_pet(animal_type='hamster', pet_name='harry')<=>describe_pet(pet_name='harry', animal_type='hamster')
输出结果均为:
I have a harry.
My harry's name is Hamster.
I have a hamster.
My hamster's name is Harry.
I have a dog.
My dog's name is Willie.
- 等效的函数调用
鉴于可以混合使用位置实参、关键字实参和默认值--通常有多种等效的函数调用方式。 - 避免实参错误
- 提供的实参多余或少于函数完成工作所需的信息时--出现实参不匹配错误。
- 看traceback报错定位错误。
3. 返回值
- 函数并非总是显示输出,可以处理数据并返回一个或一组值。
- 返回值:函数返回的值。
- 可使用return语句将值返回到调用函数的代码行。
- 可以简化主程序,将繁重工作移到函数中完成。
- 返回简单值
- 需要提供一个变量,用于存储返回的值。
- 让实参变成可选的
- 实际上是合理的使用默认值。
- 默认值要作为最后一个形参。
- 可选值让函数能够处理各种不同情形的同时,确保函数调用尽可能简单。
- 返回字典
- 函数可返回任何类型的值,包括列表、字典。
- 结合使用函数和while循环
- 注意要定义退出条件。
- 尽可能容易退出--每次提示用户输入时都提供退出循环的简单途径。(可以使用break语句)
4. 传递列表
- 向函数传递列表很有用。
- 将列表传递给函数后,函数就能直接访问列表内容。
- 在函数中修改列表
- 将列表传递给函数后,函数可对其进行修改。
- 在函数中对这个列表所做的任何修改都是永久性的。
- 使用函数更容易扩展和维护。
- 禁止函数修改列表
- 有时需要禁止函数修改列表。
- 可向函数传递列表的副本而不是原件,这样函数的修改都只影响副本(
列表名[:]
就是副本),而不影响原件。
示例:function_name(list_name[:])
(切片表示法创建副本) - 虽然向函数传递列表副本可以保留列表原始内容,但除非有充分理由需要传递副本,否则还是应该传递原始列表,来避免花时间和内存来创建副本,来提高效率。
5. 传递任意数量的实参
- 有时候,预先不知道函数需要接受多少个实参。
- Python允许函数从调用语句中收集任意数量的实参。
- 定义形参时用
*形参名
,星号让Python创建空元组,并将收到的所有值都封装到这个元组中。
例:
def make_pizza(*toppings):#星号让Python创建名为toppings的空元组
"""打印顾客点的所有配料"""
print(toppings)
make_pizza('pepperoni')
make_pizza('mushrooms','green peppers', 'extra cheese')
输出:
('pepperoni',)
('mushrooms', 'green peppers', 'extra cheese')
- 结合使用位置实参和任意数量实参
- 如果要让函数接受不同类型的实参,必须在函数定义中将接纳任意数量实参的形参放在最后。
(其实道理也能想明白,要不然不知道到底停到哪个算结束) - Python先匹配位置实参和关键字实参,再将余下的实参都收集到最后一个形参中。
例:
def make_pizza(size, *toppings):#星号让Python创建名为toppings的空元组
"""概述要制作的比萨"""
print("\nMaking a "+str(size)+
"-inch pizza with the following toppings:")
for topping in toppings:
print("- "+topping)
make_pizza(16,'pepperoni')
make_pizza(12,'mushrooms','green peppers', 'extra cheese')
输出:
Making a 16-inch pizza with the following toppings:
- pepperoni
Making a 12-inch pizza with the following toppings:
- mushrooms
- green peppers
- extra cheese
- 使用任意数量的关键字实参
- 有时,需要接受任意数量的实参,但预先不知道传递给函数的会是什么样的信息。
- 可将函数编写成能够接受任意数量的键-值对。
- 定义形参时用
**形参名
,2个星号让Python创建空字典,并将收到的所有名称-值对都封装到这个元组中。 - 函数中可以像访问其他字典那样访问形参对应的字典里面的名称-值对。
- 编写函数时,可以以各种方式混合使用位置实参、关键字实参和任意数量的实参。
例:
def build_profile(first,last,**user_info):#2个星号让Python创建名为user_info的空字典
"""创建一个字典,其中包含我们知道的有关用户的一切"""
profile={}
profile['first_name']=first
profile['last_name']=last
for key, value in user_info.items():
profile[key]=value
return profile
user_profile=build_profile('albert','einstein',location='princeton',field='physics')
print(user_profile)
输出:
{'first_name': 'albert', 'last_name': 'einstein', 'location': 'princeton', 'field': 'physics'}
6. 将函数储存在模块中
- 函数的优点之一--使用函数可以将代码块与主程序分离。
- 给函数指定描述性的名称--让主程序易理解。
- 将函数存储在被称为模块的独立文件中,再将模块导入到主程序中。
- import语句允许在当前程序文件中使用模块中的代码。
- 将函数存储在独立文件--隐藏程序代码的细节,将重点放在高层逻辑上。
- 可以与其他程序员共享--使用函数库。
- 导入整个模块
- 要让函数可导入,首先要创建模块。
-
模块是扩展名为.py的文件,包含要导入到程序中的代码。
例:
创建包含函数make_pizza()的模块--pizza.py,要删除了除了make_pizza()以外的全部代码。
#pizza.py
def make_pizza(size, *toppings):#星号让Python创建名为toppings的空元组
"""概述要制作的比萨"""
print("\nMaking a "+str(size)+
"-inch pizza with the following toppings:")
for topping in toppings:
print("- "+topping)
在pizza.py 同一目录下创建making_pizzas.py,调用刚创建的模块。
#making_pizzas.py
import pizza
pizza.make_pizza(16,'pepperoni')
pizza.make_pizza(12,'mushrooms','green peppers', 'extra cheese')
输出:
Making a 16-inch pizza with the following toppings:
- pepperoni
Making a 12-inch pizza with the following toppings:
- mushrooms
- green peppers
- extra cheese
- 执行
import pizza
Python打开文件pizza.py,并将其中所有函数都复制到这个程序中(幕后的,看不见)。 - 调用语法格式:
module_name.function_name
这种方式可以使用该模块中的所有函数。
- 导入特定的函数
- 导入语法格式:
from module_name import function_name
导入模块中的特定函数。 - 导入语法格式:
from module_name import function_0, function_1, function_2
导入模块中的任意数量的特定函数。 - 这种语法因为import语句中显式导入了函数,因此调用时不需要用有句点的
模块名.函数名
,可以指定名称直接调用该函数。
例(输出和之前的一样,只是可以直接调用函数了):
from pizza import make_pizza
make_pizza(16,'pepperoni')
make_pizza(12,'mushrooms','green peppers', 'extra cheese')
- 使用as给函数指定别名
- 要导入的函数名与程序现有名称冲突,或 函数名太长--可指定简短、独一无二的别名--函数的另一个名称。
- 要给函数指定别名,必须在导入它时这样做。
- 给函数指定别名语法:
from module_name import function_name as fn
-
此时不能用function_name()。用function_name()会报错,或者即使不报错但是调用却的是现有程序里的同名称的函数,而非module_name里的函数!
例:
from pizza import make_pizza as mp
#此时用make_pizza()就会报错,或者不报错但是调用却的是现有程序里的,而非pizza里的
mp(16,'pepperoni')
mp(12,'mushrooms','green peppers', 'extra cheese')
- 使用as给模块指定别名
- 不再专注于模块名,而专注于描述性的函数名。
- 给模块指定别名语法:
import module_name as mn
- 同上,此时不能用module_name.funcition_name(),只能用mn.function_name()。
例:
import pizza as p
p.make_pizza(16,'pepperoni')
p.make_pizza(12,'mushrooms','green peppers', 'extra cheese')
- 导入模块中所有函数--星号*运算符
- 使用星号*运算符可以让Python导入模块中所有函数。
- 这时可以直接通过名称调用函数,而不用使用句点表示法。
-
语法:
from module_name import *
- 注意:在使用非自己编写的大型模块时,最好不要采用这种导入方法:如果模块中有函数名称和项目中使用的名称冲突,可能会覆盖。
- 最佳做法:要么只导入需要使用的函数,要么导入整个模块并使用句点表示法。
7. 函数编写指南
牢记几个细节:
- 应给函数、模块指定描述性名称,并且只在其中使用小写字母和下划线。
- 函数应包含简要阐述其功能的注释,该注释应紧跟在函数定义后面,采用文档字符串格式。
- 给形参指定默认值时,等号两边不留空格:
def function_name(parameter_0, paramater_1='default value')
- 对于函数调用中的关键字实参,等号两边不留空格:
function_name(value_0, parameter_1='value')
- 建议代码行长度不超过79字符。
- 程序或模块包含多个函数时,相邻的函数用两个空行分开。
- 所有import都应放在最开头,除非有注释描述整个程序可以放到import前面。
- 形参过多时,可以按如下格式:
def function_name(
parameter_1, paramater_2, paramater_3,
paramater_4, paramater_5):
function_body
我的问题:函数名相同形参不同的函数算相同的函数吗?这种复用可以吗?
我的测试结果:
名称相同的函数再定义时会覆盖!所以似乎是不行的。
网友评论