Python基本语法
一、Python介绍
Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。
Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有比其他语言更有特色语法结构。
Python 是一种解释型语言: 这意味着开发过程中没有了编译这个环节。类似于PHP和Perl语言。
Python 是交互式语言: 这意味着,您可以在一个Python提示符,直接互动执行写你的程序。
Python 是面向对象语言: 这意味着Python支持面向对象的风格或代码封装在对象的编程技术。
Python 是初学者的语言:Python 对初级程序员而言,是一种伟大的语言,它支持广泛的应用程序开发,从简单的文字处理到 WWW 浏览器再到游戏。
二、发展历程
Python 是由 Guido van Rossum 在八十年代末和九十年代初,在荷兰国家数学和计算机科学研究所设计出来的。
Python 本身也是由诸多其他语言发展而来的,这包括 ABC、Modula-3、C、C++、Algol-68、SmallTalk、Unix shell 和其他的脚本语言等等。
像 Perl 语言一样,Python 源代码同样遵循 GPL(GNU General Public License)协议。
现在 Python 是由一个核心开发团队在维护,Guido van Rossum 仍然占据着至关重要的作用。
三、Python的特点
易于学习:Python有相对较少的关键字,结构简单,和一个明确定义的语法,学习起来更加简单。
易于阅读:Python代码定义的更清晰。
易于维护:Python的成功在于它的源代码是相当容易维护的。
一个广泛的标准库:Python的最大的优势之一是丰富的库,跨平台的,在UNIX,Windows和Macintosh兼容很好。
互动模式:互动模式的支持,您可以从终端输入执行代码并获得结果的语言,互动的测试和调试代码片断。
可移植:基于其开放源代码的特性,Python已经被移植(也就是使其工作)到许多平台。
可扩展:如果你需要一段运行很快的关键代码,或者是想要编写一些不愿开放的算法,你可以使用C或C++完成那部分程序,然后从你的Python程序中调用。
数据库:Python提供所有主要的商业数据库的接口。
GUI编程:Python支持GUI可以创建和移植到许多系统调用。
可嵌入: 你可以将Python嵌入到C/C++程序,让你的程序的用户获得"脚本化"
四、Pycharm及python安装详细教程
4.1. 安装python
4.1.1.python下载地址
进入之后如下图,选择图中红色圈中区域进行下载
image.png
4.1.2. 下载完成后如下图所示
image.png
4.1.3. 安装
双击exe文件进行安装,如下图,并按照圈中区域进行设置,切记要勾选打钩的框,然后再点击Customize installation进入到下一步:
image.png
image.png
image.png
4.1.4. 自定义安装路径
对于上图中,可以通过Browse进行自定义安装路径,也可以直接点击Install进行安装,点击install后便可以完成安装了。
image.png
4.1.5. 检测安装是否成功
为了检查我们的python是否安装成功,可以在命令窗口中输入python进行查询,如显示下图一的信息则表示成功了,如显示第二张图的信息则表示出错了。
image.png
4.2. 安装pycharm
4.2.1.下载地址
首先从网站下载pycharm,进入之后如下图,根据自己电脑的操作系统进行选择,对于windows系统选择图中红色圈中的区域。
image.png
4.2.2. 下载完成之后如下图:
image.png
4.2.3. 直接双击下载好的exe文件进行安装,安装截图如下:
image.png
点击Next进入下一步:
image.png
点击Next进入下一步:
image.png
点击Install进行安装:
image.png
image.png
安装完成后出现下图界面,点级Finish结束安装:
image.png
下面我们来创建自己的第一个程序:
1、单击桌面上的pycharm图标,进入到pycharm中,如下图所示:
image.png
2、我们选择第二个,然后点击Ok:
image.png
3、点击上图中的Accept进入下一步:
image.png
4、点击上图中的ok进入下一步:
image.png
5、点击Create New Project,进入如下图的界面,图中的Location是选择你安装的python的位置,选择好后,点击create。
image.png
五、第一个Python程序
1.创建python file
2.练习打印hello world
image.png
六、Python变量和数据类型
6.1. 变量的定义
在程序中,有时我们需要对2个数据进行求和,那么该怎样做呢?
大家类比一下现实生活中,比如去超市买东西,往往咱们需要一个菜篮子,用来进行存储物品,等到所有的物品都购买完成后,在收银台进行结账即可
如果在程序中,需要把2个数据,或者多个数据进行求和的话,那么就需要把这些数据先存储起来,然后把它们累加起来即可
在Python中,存储一个数据,需要一个叫做变量的东西,如下示例:
num1=100#num1就是一个变量,就好一个小菜篮子num2=87#num2也是一个变量result=num1+num2 #把num1和num2这两个"菜篮子"中的数据进行累加,然后放到 result变量中
说明:
所谓变量,可以理解为菜篮子,如果需要存储多个数据,最简单的方式是有多个变量,当然了也可以使用一个
程序就是用来处理数据的,而变量就是用来存储数据的
程序中:
为了更充分的利用内存空间以及更有效率的管理内存,变量是有不同的类型的,如下所示:
Python3 中有六个标准的数据类型:
image.png
Python3 的六个标准数据类型中:
不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);
可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。
注意:在python中,只要定义了一个变量,而且它有数据,那么它的类型就已经确定了,不需要咱们开发者主动的去说明它的类型,系统会自动辨别
可以使用type(变量的名字),来查看变量的类型
6.1.1 概念
整数
Python可以处理任意大小的整数,当然包括负整数,在Python程序中,整数的表示方法和数学上的写法一模一样,例如:1,100,-8080,0,等等。
浮点数
浮点数也就是小数,之所以称为浮点数,是因为按照科学记数法表示时,一个浮点数的小数点位置是可变的,比如,1.23x109和12.3x108是相等的。浮点数可以用数学写法,如1.23,3.14,-9.01,等等。
整数和浮点数在计算机内部存储的方式是不同的,整数运算永远是精确的(除法难道也是精确的?是的!),而浮点数运算则可能会有四舍五入的误差。
字符串
字符串是以''或""括起来的任意文本,比如'abc',"xyz"等等。请注意,''或""本身只是一种表示方式,不是字符串的一部分,因此,字符串'abc'只有a,b,c这3个字符。
布尔值
布尔值和布尔代数的表示完全一致,一个布尔值只有True、False两种值,要么是True,要么是False,在Python中,可以直接用True、False表示布尔值(请注意大小写),也可以通过布尔运算计算出来。
布尔值可以用and、or和not运算。
and运算是与运算,只有所有都为 True,and运算结果才是 True。A与B true true
or运算是或运算,只要其中有一个为 True,or 运算结果就是 True。
not运算是非运算,它是一个单目运算符,把 True 变成 False,False 变成 True。
空值
空值是Python里一个特殊的值,用None表示。None不能理解为0,因为0是有意义的,而None是一个特殊的空值。
6.1.2 代码示例
#整数a=1;#浮点数b=1.1;#字符串c="abc";#boolean类型d=True;#空值e=None;print(a);print(b);print(c);print(d);print(e)a=TrueandTrue# ==> Trueb=TrueandFalse# ==> Falsec=FalseandTrue# ==> Falsed=FalseandFalse# ==> Falsee=TrueorTrue# ==> Truef=TrueorFalse# ==> Trueg=FalseorTrue# ==> Trueh=FalseorFalse# ==> Falsei=notTrue# ==> Falsej=notFalse# ==> Trueprint(a,b,c,d,e,f,g,h,i,j)
说明:
在计算 a and b 时,如果 a 是 False,则根据与运算法则,整个结果必定为 False,因此返回 a;如果 a 是 True,则整个计算结果必定取决与 b,因此返回 b。
在计算 a or b 时,如果 a 是 True,则根据或运算法则,整个计算结果必定为 True,因此返回 a;如果 a 是 False,则整个计算结果必定取决于 b,因此返回 b。
所以Python解释器在做布尔运算时,只要能提前确定计算结果,它就不会往后算了,直接返回结果。
6.1.3 标识符
什么是标识符?
开发人员在程序中自定义的一些符号和名称
标识符是自己定义的,如变量名 、函数名等
标识符的命名规则
. 标识符只能由字母、下划线“_”、数字组成。. 标识符不能以数字开头。. 标识符不能使用关键字. 标识符对大小写敏感。(建议:标识符命名应“见名知意”)
python中的关键字
'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'
注释:
单行注释:
/* *///定义一个变量name="jack"
多行注释:
'''
定义一个变量
'''name="jack"
课堂思考:下列哪些标识符符合规则
ifname and my_list my_list1from#1age2listasTruewetyui height my_log qwe&qwe
标识符的命名方法
小驼峰式命名法:
函数名、变量名 addName
大驼峰式命名法:
类名 AddName
6.2.Python中print语句
print() 方法用于打印输出,最常见的一个函数。
语法:
print(*objects, sep=' ', end='\n', file=sys.stdout)
参数:
objects -- 复数,表示可以一次输出多个对象。输出多个对象时,需要用 , 分隔。
sep -- 用来间隔多个对象,默认值是一个空格。
end -- 用来设定以什么结尾。默认值是换行符 \n,我们可以换成其他字符串。
file -- 要写入的文件对象。
#直接打印print("哈哈哈哈")#多条打印print("哈哈哈哈","呵呵呵呵","吼吼吼吼"),#打印+计算print("100+200的和是:",100+200);#设置间隔符号print("www","runoob","com",sep=".") # 设置间隔符 www.runoob.com
格式化输出
方式一:使用百分号(%)字符串格式化
print("my name is %s, and my age is %d" %(name,age))
方式二:使用format字符串格式化
位置参数
print("my name is{}, and my age is{}".format(age,name))
关键字参数
print("my name is {name}, and my age is {age}".format(age=18,name="jack"))
注释:位置参数("{0}".format()),关键字参数("{关键字}".format())
6.3.设置换行符号
print(a,b,c,d,e,sep=";",end="\n");
6.4.Python中input语句
input() 用来获取控制台的输入。
语法:
input([prompt])
image.png
七、运算符
5.1 算术运算符:
以下假设变量a为10,变量b为21
image-20210115001421457.png
案例:计算a=10,b=21的算术运算符使用
a = 10b = 21print(a + b)
5.2 逻辑运算符
Python语言支持逻辑运算符,以下假设变量 a 为 10, b为 20:
image-20210115002053407.png
案例:
a = 1print(a = 1 and a = 2)
5.3 比较运算符
以下假设变量a为10,变量b为20
比较运算符.png
案例
a = 1if a >= 1: print("good")else: print("fail")
5.4 赋值运算符:
以下假设变量a为10,变量b为20:
image-20210115002959136.png
案例:
a = 1
print(a)
a += 1
print(a)
python基础--语句
目录具体内容
判断语句1:if语句的使用格式
2:if-else的使用格式
3:if-elif-else的使用格式
4:if嵌套
循环语句1:while循环的格式
2:while循环嵌套
3:for循环的格式
一、判断语句
在程序中如果某些条件满足,才能做某件事情,而不满足时不允许做,这就是所谓的判断
1.1 if语句的使用格式
if 要判断的条件: 条件成立时,要做的事情
案例:判断年纪,如果age大于18,输入成年
age = 18if age>18: print("你已成年")
注意:代码的缩进为一个tab键,或者4个空格
1.2 if-else的使用格式
if 要判断的条件: 条件成立时,要做的事情else: 条件不成立时,要做的事情
案例:判断年纪,如果age大于18,输入成年,否则未成年
age=18ifage>18:print("你已成年")else:print("你是未成年人")
1.3 if-elif-else的使用格式
if 要判断的条件: 条件成立时,要做的事情elif 要判断的条件: 条件成立时,要做的事情else: 条件不成立时,要做的事情
案例:80<score<=100,等级A;60<score<=80,等级B;剩余,等级C
score=72ifscore>80andscore<=100:print("A")elifscore>60andscore<=80:print("B")else:print("C")
1.4 if嵌套
if 要判断的条件: 条件成立时,要做的事情 if 要判断的条件: 条件成立时,要做的事情 else: 条件不成立时,要做的事情else: 条件不成立时,要做的事情
案例:公交卡上余额大于2,可以上车,否则输出请充值,上车如果座位数大于0能入座,否则请站稳扶好
monery=input("请输入金额:")ifint(monery)>2:print("请上车")seat=input("请输入剩余座位:")ifint(seat)>0:print("请入座")else:print("请站稳扶好")else:print("请充值")
二:循环语句
需要多次重复执行的代码,都可以用循环的方式来完
循环不是必须要使用的,但是为了提高代码的重复使用率
2.1 while循环
2.1.1 while循环的格式
while 条件: 条件成立时,要做的事情 条件成立时,要做的事情 .....
案例:循环打印1~100的数据和
i=1sum=0whilei<=100:sum+=i i=i+1print(sum)
练习:计算1--100之间的偶数和(包含1和100)
i=1sum=0whilei<=100:ifi%2==0:sum+=i i+=1print("1~100之间的所有的偶数和:%d"%sum)
2.1.2 while循环嵌套
while 条件: 条件成立时,要做的事情 条件成立时,要做的事情 ..... while 条件: 条件成立时,要做的事情 条件成立时,要做的事情 .....
练习
用嵌套打印五边三角形
***************
i=1whilei<=5:j=1whilej<=i:print("*",end="")j+=1print("\n")i+=1
练习打印如下图形
***************
打印九九乘法口诀
1*1=1 2*1=2 2*2=4 3*1=3 3*2=6 3*3=9 4*1=4 4*2=8 4*3=12 4*4=16 5*1=5 5*2=10 5*3=15 5*4=20 5*5=25 6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81
代码
i=1whilei<=9:j=1whilej<=i:print("%d*%d=%d"%(i,j,i*j),end=" ")j+=1print("\n")i+=1
2.2 for循环
2.2.1 for循环的格式
for 临时变量 in 列表或者字符串等可迭代对象: 循环满足条件时执行的代码
练习
字符串循环打印
name="jack"foriinname:print(i)
打印0到9的数据
foriinrange(10):print(i)
break/continue/return
continue的作用:当满足条件时,用来结束本次循环,紧接着执行下一次的循环break的作用:满足条件时,立刻结束break所在的循环
案例:while循环1到9,当数字是3,跳出本次循环,执行其他循环
i=0whilei<=9:i+=1ifi==3:continueprint(i)
案例:while循环1到9,当数字是3,停止循环
i=0whilei<=9:i+=1ifi==3:breakprint(i)
注意点:
break/continue只能用在循环中,除此以外不能单独使用
break/continue在嵌套循环中,只对最近的一层循环起作用
4. pass的使用
pass作用
1.Pythonpass是空语句,是为了保持程序结构的完整性。2.pass不做任何事情,一般用做占位语句。
foriinrange(10):pass
作业
1:使用循环(任意一种)计算0--100之间所有奇数的和2:
补充:break/continue/return区别
Python列表
一、列表的介绍
思考:前面学习的字符串可以用来存储一串信息,那么想一想,怎样存储咱们班所有同学的名字呢?
定义100个变量,每个变量存放一个学生的姓名可行吗?有更好的办法吗?
1.1 格式
变量=[,,,]
案例
namesList=['xiaoWang','xiaoZhang','xiaoHua']
案例:不同类型
namesList=['xiaoWang',12,[1,2,3],(1,2)]
二、列表的相关操作
列表
names1=['xiaoWang','xiaoZhang','xiaoHua']names2=[23,34,45]name='anfly'
2.1 列表的新增
append, extend, insert
2.1.1 append
案例:列表和字符串
names1.append(name)print(names1)
输出:
['xiaoWang','xiaoZhang','xiaoHua','anfly']
案例:列表和列表
names1.append(names2)print(names1)#['xiaoWang', 'xiaoZhang', 'xiaoHua', [23, 34, 45]]
2.1.2 extend
案例:列表和字符串
names1.extend(name)print(names1)#['xiaoWang', 'xiaoZhang', 'xiaoHua', 'a', 'n', 'f', 'l','y']
案例:列表和字符串
names1.extend(names2)print(names1)#['xiaoWang', 'xiaoZhang', 'xiaoHua', 23, 34, 45]
extend和append区别
append的最终列表中添加的是一个元素,extend的最终列表中显示的是追加的多个元素
2.1.3 insert
指定对应索引新增数据
names1.insert(1,name)print(names1)#['xiaoWang', 'jack', 'xiaoZhang', 'xiaoHua']
思考:如果新增的索引不存在?会出现什么问题(会默认添加到最后)
names1.insert(111,name)print(names1)#['xiaoWang', 'xiaoZhang', 'xiaoHua', 'jack']
2.2 列表的修改
修改元素的时候,要通过下标来确定要修改的是哪个元素,然后才能进行修改
2.2.1 索引修改
案例:索引存在时修改
names1[0]="xiaoli"print(names1)#['xiaoli', 'xiaoZhang', 'xiaoHua']
案例:索引不存在时修改
names1[10]="xiaoli"print(names1)#IndexError: list assignment index out of range
2.3 列表的删除
del:根据下标进行删除pop:删除最后一个元素remove:根据元素的值进行删除
2.3.1:del
案例
delnames1[0]print(names1)#['xiaoZhang', 'xiaoHua']
2.3.2 pop(默认最后一个元素)
案例
names1.pop()print(names1)#['xiaoWang', 'xiaoZhang']
2.3.3 remove
案例
names1.remove("xiaoWang")print(names1)#['xiaoZhang', 'xiaoHua']
2.4 列表的查询
index, count
2.4.1:index
index查询列表中的元素,如果存在就返回给元素的索引,不存在就报错
案例
print(names1.index("xiaoZhang"))#1print(names1.index("xiaoZhang1"))#ValueError: 'xiaoZhang1' is not in list
2.4.2 count
count查询列表中的元素的个数
案例
print(name.count("c"))#1
2.5:列表的排序
sort方法是将list按特定顺序重新排列,默认为由小到大,参数reverse=True可改为倒序,由大到小。
reverse方法是将list反转
案例:排序
nums=[34,22,15,68,89]nums.sort()print(nums)#[15, 22, 34, 68, 89]
案例:反转
nums=[34,22,15,68,89]nums.reverse()print(nums)#[89, 68, 15, 22, 34]
2.6 列表的循环取值
方式一:for循环
namesList=['xiaoWang','xiaoZhang','xiaoHua']fornameinnamesList:print(name)
方式二:while循环
namesList=['xiaoWang','xiaoZhang','xiaoHua']length=len(namesList)i=0whilei<length:print(namesList[i])i+=1
2.7 列表的嵌套
类似while循环的嵌套,列表也是支持嵌套的
格式
变量名=[,[,]]
案例
names=['xiaoWang','xiaoZhang','xiaoHua',["xiaomi","xiaolan"]]
作业:
schoolNames=[['北京大学','清华大学'],['南开大学','天津大学','天津师范大学'],['浙江大学'],['河北大学','河北科技大学']]
1:利用下标索引取出 河北科技大学print(schoolNames[3][1])2:删除 河北大学del schoolNames[3][0]3:插入 河北农业大学schoolNames[3].insert(1,"河北农业大学")
names=['xiaoWang','xiaoZhang','xiaoHua',["xiaomi","xiaolan"]]names[3].insert(2,"xiaohua")print(names)
python--元组和字典
一、元组
Python的元组与列表类似,不同之处在于元组的元素不能修改。元组使用小括号,列表使用方括号。
1.1 元组的格式
格式
变量名=(,,,,)
案例
aTuple=(23,35,56,34,11,21)
1.2 访问元组
通过索引取数据
案例:索引值存在
aTuple=(23,35,56,34,11,21)print(aTuple[2])#56
案例:索引值不存在
aTuple=(23,35,56,34,11,21)print(aTuple[20])#IndexError: tuple index out of range
1.3 查询个数
count查询出现的个数
案例
aTuple=('b','c','d','e','f','g')print(aTuple.count('d'))#1
1.4 查询索引
index:查询元素的索引,有对应的元素返回对应的索引,否则报错
案例:有对应的元素
aTuple=('b','c','d','e','f','g')print(aTuple.index('d',0,4))#2
案例:无对应的元素
aTuple=('b','c','d','e','f','g')print(aTuple.index('d',0,1))#ValueError: tuple.index(x): x not in tuple
1.5 修改数据(不能修改)
案例
aTuple=('b','c','d','e','f','g')aTuple[1]=23#TypeError: 'tuple' object does not support item assignment
1.6 类型转换
列表转换元组
案例
aa=[23,34,45,56,67]tuple(aa)print(aa)#[23, 34, 45, 56, 67]
元组转换列表
案例
aTuple=('b','c','d','e','f','g')a=list(aTuple)print(a)#['b', 'c', 'd', 'e', 'f', 'g']
1.7 元组的循环取值
方式一:for
aTuple=('b','c','d','e','f','g')foriinaTuple:print(i)
方式二:while
aTuple=('b','c','d','e','f','g')i=0whilei<len(aTuple):print(aTuple[i])i=i+1
二、字典
2.1 字典的格式
格式
变量名={key1:value,key2:value,,,}
案例
info={"name":"anfly","age":12,"sex":"男"}
字典的每个元素由2部分组成,键(key):值(value)
2.2 根据键访问值
案例:有对应key的
info={"name":"anfly","age":18,"sex":"男"}print(info["name"])#anfly
案例:无对应key的
info={"name":"anfly","age":12,"sex":"男"}print(info["name12"])#KeyError: 'name12'
思考:假如我们不确定字典中是否存在某个键而又想获取其值时,如何操作?
案例:有对应key的
info={"name":"anfly","age":12,"sex":"男"}print(info.get("name"))#anfly
案例:无对应key的
info={"name":"anfly","age":12,"sex":"男"}print(info.get("name"))#None
案例:无对应key的,默认返回数据
info={"name":"anfly","age":12,"sex":"男"}print(info.get("name12","无数据"))#无数据
2.3 修改元素
字典的每个元素中的数据是可以修改的,只要通过key找到,即可修改,否则是新增
案例:对应的key
info={"name":"anfly","age":12,"sex":"男"}info["age"]=14print(info)#{'name': 'anfly', 'age': 14, 'sex': '男'}
案例:无对应的key
info={"name":"anfly","age":12,"sex":"男"}info["gender"]="属鸡"print(info)#{'name': 'anfly', 'age': 12, 'sex': '男', 'gender': '属鸡'}
总结
有对应的key则是修改数据,没有对应的key是新增数据
2.4 添加元素
案例:
info={"name":"anfly","age":12,"sex":"男"}info["gender"]="属鸡"print(info)#{'name': 'anfly', 'age': 12, 'sex': '男', 'gender': '属鸡'}
2.5 删除元素
del,clear() ---- 清空
2.5.1 del (删除指定的元素)
案例:删除整个字典
info={"name":"anfly","age":12,"sex":"男"}delinfoprint(info)#NameError: name 'info' is not defined
案例:删除某个元素
info={"name":"anfly","age":12,"sex":"男"}delinfo["name"]print(info)#{'age': 12, 'sex': '男'}
2.5.2 clear清空
案例:
info={"name":"anfly","age":12,"sex":"男"}info.clear()print(info)#{}
2.6 查询长度
len():查询键值对的个数
案例
info={"name":"anfly","age":12,"sex":"男"}print(len(info))#3
2.7 字典中循环
案例:取出字典中的key
info={"name":"anfly","age":12,"sex":"男"}foriininfo.keys():print(i)
结果:name age sex
案例:取出字典中的value
info={"name":"anfly","age":12,"sex":"男"}foriininfo.values():print(i)
结果:anfly 12 男
取出字典中的key和value
方式一:
info={"name":"anfly","age":12,"sex":"男"}foriininfo.keys():print(i,info[i])
方式二:
info={"name":"anfly","age":12,"sex":"男"}fork,vininfo.items():print(k,v)
扩充
如何实现带下标索引的遍历?
for i in 可迭代: print(i)
enumerate()实现索引的遍历
names=["anfly","tom","Meachal"]fori,chrinenumerate(names):print(i,chr)
返回值
0 anfly
1 tom
2 Meachal
集合和函数
一、集合
1.1 集合的特征
集合是无序的,集合中的元素是唯一的,集合一般用于元组或者列表中的元素去重
1.2 集合的格式
格式
变量名=set()变量名.add(元素)# 必须不能初始化值
或
变量名={元素,元素,,,}
注意:下面写法为一个空字典,为空默认是字典,如果有数据在根据格式判断为字典还是集合
name={}
1.3 添加元素
1.3.1 add
案例
nums={11,24,45,96,28}nums.add(42)print(nums)#{96, 42, 11, 45, 24, 28}
1.3.2 update
案例
nums={11,24,45,96,28}nums2=["anfly","tom"]nums.update(nums2)print(nums)#{96, 'anfly', 11, 45, 24, 28, 'tom'}
1.4:删除元素
remove,pop,discard
1.4.1 remove
使用remove删除集合中的元素 如果有直接删除 如果没有程序报错
案例:该元素存在
nums={11,24,45,96,28}nums.remove(24)print(nums)#{96, 11, 45, 28}
案例:该元素不存在
nums={11,24,45,96,28}nums.remove(245)print(nums)#KeyError: 245
1.4.2 pop
1、如果集合的元素都是数字, 删除时, 删掉的是最小的数字, 其余数字升序排列2、如果集合的元素是非数字, 删除时, 删掉的是随机的元素, 其余元素随机排列3、如果集合里既有数字又有非数字元素, 删除时:若删掉的是数字, 则一定是删掉了最小的, 其他数字升序排列, 非数字元素随机排列;若删掉的非数字, 则一定是随机删掉了一个, 其他数字升序排列, 非数字则随机排列.如果集合没有元素程序报错
案例:有元素
nums={11,24,45,96,28}nums.pop()print(nums)#{11, 45, 24, 28}
案例:无元素
nums={}nums.pop()print(nums)#TypeError: pop expected at least 1 arguments, got 0
1.4.3 discard
使用discard删除 如果元素存在直接删除 如果元素不存在不做任何操作
案例:该元素存在
nums={11,24,45,96,28}nums.discard(24)print(nums)#{96, 11, 45, 28}
案例:该元素不存在
nums={11,24,45,96,28}nums.discard(242)print(nums)#{96, 11, 45, 24, 28}
1.5:集合的交集和并集
1.5.1:交集
使用&连接多个集合,得到相同的元素
案例:存在相同元素
set1={"anfly","tom","haha"}set2={"anfly","susala"}set3=set1&set2print(set3)
返回值:{'anfly'}
案例:存在相同元素
set1={"anfly","tom","haha"}set2={"anfly2","susala"}set3=set1&set2print(set3)
返回值:set()
1.5.2:并集
使用|连接多个集合,得到全部集合中全部的元素
案例:
set1={1,2,3,4}set2={3,4,5,6}new_set=set1|set2print(new_set)#{1, 2, 3, 4, 5, 6}
1.6 公共方法
1.6.1:运算符
image-20210118195122815.png
(1)加法
image-20210118195528110.png
(2)乘法
image-20210118195549097.png
[图片上传失败...(image-3e9eb6-1618241534738)]
(3)in
image-20210118195609362.png
1.6.2:python中的内置函数
image-20210118195732142.png
(1)长度:len()
image-20210118195807771.png
(2)最大值:max()
image-20210118195846907.png
(3)删除:del()
image-20210118195927830.png
二、函数
2.1 什么是函数
在开发程序时,需要某块代码多次,但是为了提高编写的效率以及代码的重用,所以把具有独立功能的代码块组织为一个小模块,这就是函数
2.2 函数定义和调用
格式
def函数名():执行语句函数名()#调用函数
案例
defhello():print("hello word")hello()
注意:
定义了函数之后,就相当于有了一个具有某些功能的代码,想要让这些代码能够执行,需要调用它调用函数很简单的,通过 函数名()即可完成调用每次调用函数时,函数都会从头开始执行,当这个函数中的代码执行完毕后,意味着调用结束了当然了如果函数中执行到了return也会结束函数
2.3 函数参数
思考:现在需要定义一个函数,这个函数能够完成2个数的加法运算,并且把结果打印出来,该怎样设计?
案例
defadd2num():a=11b=22c=a+bprintc
思考:如果为了让一个函数更通用,即想让它计算哪两个数的和,就让它计算哪两个数的和,在定义函数的时候可以让函数接收数据?
引入:参数传递
2.3.1:位置参数
格式
def函数名(参数1,参数2):代码块函数名(值1,值2)
案例:
deffun(a,b):print("a:",a)print("b:",b)fun(2,3)
结果:a: 2 b:3
小总结定义时小括号中的参数,用来接收参数用的,称为 “形参”调用时小括号中的参数,用来传递给函数用的,称为 “实参”
2.3.2 关键字参数
格式
def函数名(参数1,参数2):代码块函数名(参数1=值1,参数2=值2)
案例:
deffun(a,b):print("a:",a)print("b:",b)fun(a=2,b=3)
结果:a: 2 b:3
注意:参数调用时,可以改变传参顺序,如果有位置参数需要位置参数放在关键字参数前面
案例:
deffun(a,b):print("a:",a)print("b:",b)fun(3,b=2)
结果:a: 3 b:2
如果关键字参数传参要在位置参数之前,将会报错
案例:错误
deffun(a,b):print("a:",a)print("b:",b)fun(a=3,2)#SyntaxError: positional argument follows keyword argument
2.3.3:缺省参数
在形参中默认有值的参数,称之为缺省参数
案例:调用函数时,缺省参数的值没有传入
defprintinfo(name,age=20):print("name:",name)print("age:",age)printinfo(name="anfly")#name: anfly#age: 20
案例:调用函数时,缺省参数的值传入
defprintinfo(name,age=20):print("name:",name)print("age:",age)printinfo(name="anfly",age=10)#name: anfly#age: 10
案例
defprintinfo(age=20,name):print("name:",name)print("age:",age)printinfo(name="anfly",age=10)#SyntaxError: non-default argument follows default argument
总结
调用函数时,缺省参数的值如果没有传入,则取默认值(形式参数),如果传入,则取实际参数缺省参数一定要位于位置参数的最后面
2.3.4 不定长参数
有时可能需要一个函数能处理比当初声明时更多的参数, 这些参数叫做不定长参数,声明时不会命名。
格式
defprintinfo(*args,**kwargs):print("args:",args)print("kwargs:",kwargs)printinfo(参数)
注意:加了星号(*)的变量args会存放所有未命名的变量参数,args为元组 而加**的变量kwargs会存放命名参数,即形如key=value的参数, kwargs为字典
案例:不定长参数* args
defprintinfo(*args):print("args:",args)printinfo(100,200,300,400)#args: (100, 200, 300, 400)
案例:* args不能接收key=value类型的参数
defprintinfo(*args):print("args:",args)printinfo(100,200,300,b=400)#TypeError: printinfo() got an unexpected keyword argument 'b'
案例:不定长参数* * kwargs
defprintinfo(**kwargs):print("kwargs:",kwargs)printinfo(a=100,b=200,c=300,d=400)#kwargs: {'a': 100, 'b': 200, 'c': 300, 'd': 400}
案例:* * kwargs不能接收未命名的变量参数
defprintinfo(**kwargs):print("kwargs:",kwargs)printinfo(100,b=200,c=300,d=400)#TypeError: printinfo() takes 0 positional arguments but 1 was given
2.3.5:参数位置顺序
格式
deffun(位置参数,*args,缺省参数,**kwargs):代码块fun(参数值)
案例
defsun(a,*args,b=22,**kwargs):print("a:",a)print("args:",args)print("b:",b)print("kwargs:",kwargs)sun(100,200,300,b=2,m=3,n=4)
返回值:
a: 100 args: (200, 300)b: 2kwargs: {'m': 3, 'n': 4}
注意:•如果很多个值都是不定长参数,那么这种情况下,可以将缺省参数放到 *args的后面, 但如果有**kwargs的话,**kwargs必须是最后的
2.4:函数返回值
场景:•我给儿子10块钱,让他给我买包烟。这个例子中,10块钱是我给儿子的,就相当于调用函数时传递到参数,让儿子买烟这个事情最终的目标是,让他把烟给你带回来然后给你对么,,,此时烟就是返回值
格式
defsum():代码块return值sum()
代码
defsum(a,b):returna+bsum(1,2)
代码:查看返回值
defsum(a,b):returna+bresult=sum(1,2)#保存函数的返回值print(result)
2.4.1:多个return
defcreate_nums(num):print("---1---")ifnum==100:print("---2---")returnnum+1# 函数中下面的代码不会被执行,因为return除了能够将数据返回之外,还有一个隐藏的功能:结束函数print("return执行之后不会继续执行")print(“1231223")else:print("---3---")returnnum+2print("---4---")result1=create_nums(100)print(result1)# 打印101result2=create_nums(200)print(result2)# 打印202
注意:一个函数中可以有多个return语句,但是只要有一个return语句被执行到,那么这个函数就会结束了,因此后面的return没有什么用处
2.4.2:返回多个数据
代码
defdivid(a,b):shang=a//b#取模yushu=a%b#取余returnshang,yushu#默认是元组result=divid(5,2)print(result)# 输出(2, 1)
总结:return后面可以是元组,列表、字典等,只要是能够存储多个数据的类型,就可以一次性返回多个数据
2.5:函数类型
分类:
1. 无参数,无返回值2. 无参数,有返回值3. 有参数,无返回值4. 有参数,有返回值
2.5.1:无参数,无返回值的函数
此类函数,不能接收参数,也没有返回值,一般情况下,打印提示灯类似的功能,使用这类的函数
defprintMenu():print('--------------------------')print(' xx涮涮锅 点菜系统')print('')print(' 1. 羊肉涮涮锅')print(' 2. 牛肉涮涮锅')print(' 3. 猪肉涮涮锅')print('--------------------------')
2.5.2:无参数,有返回值的函数
•此类函数,不能接收参数,但是可以返回某个数据,一般情况下,像采集数据,用此类函数
defgetTemperature():# 这里是获取温度的一些处理过程# 为了简单起见,先模拟返回一个数据return24
2.5.3:有参数,无返回值的函数
•此类函数,能接收参数,但不可以返回数据,一般情况下,对某些变量设置数据而不需结果时,用此类函数
2.5.4:有参数,有返回值的函数
•此类函数,不仅能接收参数,还可以返回某个数据,一般情况下,像数据处理并需要结果的应用,用此类函数
# 计算1~num的累积和(案例需实际演示)defcalculateNum(num):result=0i=1whilei<=num:result=result+i i+=1returnresult
2.6:函数的嵌套
一个函数里面又调用了另外一个函数,这就是所谓的函数嵌套调用
案例
deftestb():print("testb start")print("testb testb 执行")print("testb end")deftesta():print("testa start")testb()print("testa end")
返回值
testa starttestb starttestb testb 执行testbendtestaend
注意:如果函数A中,调用了另外一个函数B,那么先把函数B中的任务都执行完毕之后才会回到上次 函数A执行的位置
课堂作业
写一个函数求三个数的和,并返回结果写一个函数求三个数的平均值,并返回结果再写一个函数求每个数与平均值之间的差,并返回结果
写一个函数打印一条横线打印自定义行数的横线
# 打印一条横线defprintOneLine():print("-"*30)# 打印多条横线defprintNumLine(num):i=0# 因为printOneLine函数已经完成了打印横线的功能,# 只需要多次调用此函数即可whilei<num:printOneLine()i+=1printNumLine(3)
2.8:匿名函数
lambda函数也叫匿名函数,即函数没有具体的名称
代码
g=lambdax:x+1print(g(1))
defg(x):returnx+1print(g(1))
注意:lambda函数可以赋值给变量,默认是返回的,所以不用再加return关键字
注释:例如g=lambdax:x+1,可以看成如下函数,冒号前是参数,可以有多个,用逗号隔开,冒号右边的返回值
三、变量
3.1:局部变量
定义
局部变量,就是在函数内部定义的变量
约束
其作用范围是这个函数内部,即只能在这个函数中使用,在函数的外部是不能使用的
代码
deftest1():a=120print("我是局部变量a:",a)a=240print("修改之后的局部变量a:",a)deftest2():a=360print("我是test02函数中的局部变量a",a)test1()test2()
返回值
我是局部变量a: 120修改之后的局部变量a: 240我是test02函数中的局部变量a 360
注意:局部变量的作用,为了临时保存数据需要在函数中定义变量来进行存储当函数调用时,局部变量被创建,当函数调用完成后这个变量就不能够使用了
3.2:全局变量
定义
在函数外边定义的变量叫做全局变量
约束
全局变量能够在所有的函数中进行访问
代码
a=100deftest1():print(a)# 虽然没有定义变量a但是依然可以获取其数据deftest2():print(a)# 虽然没有定义变量a但是依然可以获取其数据# 调用函数test1()test2()
返回值: 100 100
3.2.1 全局变量和局部变量名字相同
代码
a=100#全局变量deftest1():a=300print("修改后的a:",a)deftest2():print(a)# 调用函数test1()test2()
返回值: 修改后的a:300 100
注意:函数中的变量修改不会导致全局变量改变
3.2.2:全局变量的修改
代码:global的使用
a=100#全局变量deftest1():globala#将a变成全局变量a=300print("修改后的a",a)deftest2():print(a)# 调用函数test1()test2()
注意:在函数中出现global全局变量的名字 那么这个函数中即使出现和全局变量名相同的变量名=数据 也理解为对全局变量进行修改,而不是定义局部变量
扩展
在一个函数中需要对多个全局变量进行修改,那么可以使用
globala,b# 还可以用多次global声明都是可以的globalaglobalb
python的文件操作和异常处理
目录具体内容
文件操作1:文件操作介绍
2:文件的打开与关闭
3:文件的读写
4:文件及文件夹的相关操作
异常处理1:异常介绍
2:捕获异常
3:异常的传递
4:抛出自定义的异常
5:异常处理中抛出异常
一、文件的介绍
1 :什么是文件?
如下图展示数据
image-20210117130855293.png
2 文件的作用
使用文件的目的:保存数据存放在磁盘
把一些存储存放起来,可以让程序下一次执行的时候直接使用,而不必重新制作一份,省时省力
二、文件的打开与关闭
思考:如果想用word编写一份简历,应该有哪些流程呢?
步骤:新建--写入数据--关闭
打开word软件,新建一个word文件写入个人简历信息保存文件关闭word软件
同样,在操作文件的整体过程与使用word编写一份简历的过程是很相似的
结论
打开文件,或者新建立一个文件读/写数据关闭文件
2.1 打开文件
在python,使用open函数,可以打开一个已经存在的文件,或者创建一个新文件open(文件名,访问模式)
格式
f=open(‘文件’,'w')或者f=open('文件','r')
如下图所示:不同的打开文件的方式
image-20210117131807308.png
常见的文件操作有:写,读,追加
2.1.1 写数据(write)
格式
对象=open("文件",w)对象.write("写入数据")对象.close
案例:以写的方式打开文件,写入数据
f=open('test.txt','w')f.write('hello world, i am here!')f.close()
继续写入数据
f=open('test.txt','w')f.write('I love you')f.close()
总结:
如果文件不存在那么创建,如果存在那么就先清空,然后写入数据
2.1.2 读数据(read)
案例:以读的方式打开文件,读取数据
格式
对象 = open("文件",r)变量 = 对象.read()print(变量)
案例:读取文件(test.txt)
f=open('test.txt','r')content=f.read()print(content)
总结:
如果用open打开文件时,如果使用的"r",那么可以省略,即只写open('test.txt')如果没有文件,打开报错,存在该文件才能操作如果文件中存在中文显示,会出现乱码需要添加encoding='utf-8'open(‘test.txt’,”r”,encoding='utf-8')
思考:如果只想读取几个字怎么操作?
案例:读取指定长度的数据(单位是字节)
f = open('test.txt', 'r')content = f.read(5) # 最多读取5个数据print(content)
注意:
使用read(num)可以从文件中读取数据,num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据
2.1.3 读数据(readlines)
就像read没有参数时一样,readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素
格式
对象=open("文件",r)变量=对象.readlines()print(变量)
案例:读取文件(test.txt)
f = open('test.txt', 'r')content = f.readlines()print(content)print(type(content))
2.1.4 读数据(readline)
readline可以按照行的方式把整个文件中的内容进行一行一行的读取
格式
对象=open("文件",r)变量=对象.readline()print(变量)
案例,一行一行读取
f=open('a.txt','r',encoding='utf-8')whileTrue:content=f.readline()ifcontent:print(content)else:break
2.1.5 可写(a)
格式
对象=open("",a)对象.write("写入数据")对象.close
案例,在文件中写入数据
f=open("test.txt",a)f.write("新的数据")对象.close
总结:
(可写)形式打开文件,如果文件不存在则创建并从头添加写入的内容,存在则原有数据后追加数据
2.1.6 读数据(rb)
格式1
对象 = open("二进制文件",rb)变量= 对象.read()print(变量)
格式2
withopen("二进制文件","rb")as对象:变量=对象.read()print(变量)
案例:使用尽可能多的方式实现读取图片
f = open('33.jpg', 'rb')content = f.read()print(content)
withopen("33.jpg","rb")asrf:res=rf.read()print(res)
使用习惯:格式2中不需要手动关闭文件,所以经常被使用
总结
如果没有文件,打开报错,存在该文件才能操作
2.1.7 写数据(wb)
格式
withopen("二进制文件","wb")as对象:变量=对象.write()print(变量)
案例:备份图片
withopen("1.jpg","rb")asrf:res=rf.read()withopen("textjpg.jpg","wb")aswf:res=wf.write(res)print(res)
2.2 关闭文件
格式
close()
2.3 思考题
如果一个文件很大,比如5G,试想应该怎样把文件的数据读取到内存然后进行处理呢?
调用read()会一次性读取文件的全部内容,如果文件有10G,内存就爆了,所以,要保险起见,可以反复调用read(size)方法�每次最多读取size个字节的内容。另外,调用readline()可以每次读取一行内容,调用readlines()一次读取所有内容并按行返回list�因此,要根据需要决定怎么调用。如果文件很小,read()一次性读取最方便;如果不能确定文件大小,反复调用read(size)比较保险;如果是配置文件,调用readlines()最方便
三、文件和文件夹的操作
文件的相关操作
有些时候,需要对文件进行重命名、删除等一些操作,python的os模块中都有这么功能
3.1 文件重命名
os模块中的rename()可以完成对文件的重命名操作
格式
importosos.rename("需要修改的文件名","新文件名")
案例:
importosos.rename("test.txt","new.txt")
3.2 删除文件
os模块中的remove()可以完成对文件的重命名操作
格式
importosos.remove("文件名")
案例:
importosos.rename("new.txt")
文件夹的相关操作
2.1 创建文件夹
os模块中的mkdir()可以完成对文件的重命名操作
2.2 获取当前目录
os模块中的getcwd()可以获取当前目录
四、异常
1:什么是异常?
异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。
一般情况下,在Python无法正常处理程序时就会发生一个异常。
异常是Python对象,表示一个错误。
当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。
演示异常
f=open("123.txt","r")#FileNotFoundError: [Errno 2] No such file or directory: '123.txt'list=[1,2,3]print(list[4])#IndexError: list index out of rangestr="jack"str.index("v")ValueError:substringnotfoundc=5/0print(c)#ZeroDivisionError: division by zero
2 异常处理
2.1 作用
捕捉异常可以使用try/except语句。try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理。如果你不想在异常发生时结束你的程序,只需在try里捕获它。
2.2 语法
以下为简单的try....except...else的语法
try:<语句>#运行别的代码except<名字>:<语句>#如果在try部份引发了'name'异常else:<语句>#如果没有异常发生
代码
try:open("qwe.txt","r")print("123")exceptFileNotFoundError:print("异常处理")else:print("没有异常")
try:open("qwe.txt","r")print("123")exceptFileNotFoundErrorasresult:print("异常处理",result)else:print("没有异常")
2.3:使用except而不带任何异常类型
你可以不带任何异常类型使用except,如下实例
语法
try:正常的操作except:发生异常,执行这块代码else:如果没有异常执行这块代码
代码
try:open("qwe.txt","r")print("123")except:print("异常处理")else:print("没有异常")
注意:以上方式try-except语句捕获所有发生的异常。但这不是一个很好的方式,我们不能通过该程序识别出具体的异常信息。因为它捕获所有的异常。
2.4:使用except而带多种异常类型
语法
try:异常的操作except(Exception1[,Exception2[,...ExceptionN]]]):发生以上多个异常中的一个,执行这块代码......................else:如果没有异常执行这块代码
代码
list=[1,2,3,4]try:open("qwe.txt","r")list[7]except(NameError,FileNotFoundError)asrese:print("出现异常")else:print("没有异常")
2.5:try-finally 语句
try-finally语句无论是否发生异常都将执行最后的代码
语法
try:<语句>finally:<语句>#退出try时总会执行
案例
try:fh=open("test.txt","r")fh.readlines()fh.close()finally:print("Error: 没有找到文件或读取文件失败")
注意:当在try块中抛出一个异常,立即执行finally块代码。
finally块中的所有语句执行后,异常被再次触发,并执行except块代码。
参数的内容不同于异常
2.6 异常的传递
代码
deffunc1():print("---func1--1---")print(num)print("---func1--2---")# def func2():# print("--func2--1---")# func1()# print("--func2--2---")deffunc3():try:print("---func3--1---")func1()print("--func3--2----")exceptExceptionasresult:print(result)print("--func3---3---")func3()#func2()
2.7:触发异常
可以使用raise语句自己触发异常
案例:输入考生的成绩(0~100)
deffunctionName(score):ifscore<0orscore>100:raiseException("Invalid score!",score)# 触发异常后,后面的代码就不会再执行functionName(200)
2.8:用户自定义异常
定义
通过创建一个新的异常类,程序可以命名它们自己的异常。异常应该是典型的继承自Exception类,通过直接或间接的方式
代码:长度不低于3为
classShortInputException(Exception):def__init__(self,length,atleast):self.length=length self.atleast=atleastdefmain():try:s=input('请输入 --> ')iflen(s)<3:# raise引发一个你定义的异常raiseShortInputException(len(s),3)exceptShortInputExceptionasresult:#x这个变量被绑定到了错误的实例print('ShortInputException: 输入的长度是 %d,长度至少应是 %d'%(result.length,result.atleast))else:print('没有异常发生')main()
五、模块
Python 模块(Module),是一个Python文件,以.py 结尾,包含了Python 对象定义和Python语句
下例是个简单的模块 aa.py:
deftest1():print("我是模块1")deftest2():print("我是模块2")
5.1:模块的引入
5.1.1:import
模块定义好后,我们可以使用 import 语句来引入模块,语法如下
importmodule1[,module2[,...moduleN]]
test.py 文件代码
importaaaa.test1()aa.test2()#我是模块1#我是模块2
导入python中的模块os/math
代码:开平方根
importmathprint(math.sqrt(4))#2
注意:一个模块只会被导入一次,不管你执行了多少次。这样可以防止导入模块被一遍又一遍地执行。
5.1.2:from…import 语句
Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中,语法如下
frommodnameimportname1[,name2[,...nameN]]
test.py 文件代码
fromaaimporttest1test1()#我是模块1
注意:只能调用导入的模块中的部分,如果想使用test2,需要如下操作
fromaaimporttest1,test2test1()test2()#我是模块1#我是模块2
思考:如果需要导入模块中的部分有很多,怎么操作?
5.1.3:from…import * 语句
把一个模块的所有内容全都导入到当前的命名空间也是可行的,只需使用如下声明:
frommodnameimport*
test.py 文件代码
fromaaimport*test1()test2()#我是模块1#我是模块2
扩展
使用__all__魔幻方法当被引入的包中有__all__=(),里面指定的才能被调用,调用的时候使用from模块名import*
aa.py
__all__=('test1','test2')deftest1():print("我是模块1")deftest2():print("我是模块2")deftest3():print("我是模块2")
test.py
fromaaimport*test1()test2()
六、Python中的包
包是一个分层次的文件目录结构,它定义了一个由模块及子包,和子包下的子包等组成的 Python 的应用环境。
简单来说,包就是文件夹,但该文件夹下必须存在init.py 文件, 该文件的内容可以为空。init.py 用于标识当前文件夹是一个包。
考虑一个在 day 目录下的 runoob1.py、runoob2.py、init.py 文件,test.py 为测试调用包的代码,目录结构如下
test.pyday|--__init__.py|--runoob1.py|--runoob2.py
源代码如下:
day/runoob1.py
defrunoob1():print"I'm in runoob1"
day/runoob2.py
defrunoob2():print"I'm in runoob2"
然后我们在 day同级目录下创建 test.py 来调用 day 包
# 导入 Phone 包fromday.runoob1importrunoob1fromday.runoob2importrunoob2runoob1()runoob2()
结果
I'minrunoob1I'minrunoob2
Python 面向对象
Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的。本章节我们将详细介绍Python的面向对象编程。
如果你以前没有接触过面向对象的编程语言,那你可能需要先了解一些面向对象语言的一些基本特征,在头脑里头形成一个基本的面向对象的概念,这样有助于你更容易的学习Python的面向对象编程。
接下来我们先来简单的了解下面向对象的一些基本特征。
面向对象技术简介
类(Class):用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
数据成员:类变量或者实例变量, 用于处理类及其实例对象的相关的数据。
方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
局部变量:定义在方法中的变量,只作用于当前实例的类。
实例变量:在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
实例化:创建一个类的实例,类的具体对象。
方法:类中定义的函数。
对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
创建类
使用 class 语句来创建一个新类,class 之后为类的名称并以冒号结尾:
classClassName:'类的帮助信息'#类文档字符串class_suite#类体
类的帮助信息可以通过ClassName.doc查看。
class_suite 由类成员,方法,数据属性组成。
实例
以下是一个简单的 Python 类的例子:
实例
# !/usr/bin/python # -*- coding: UTF-8 -*-classEmployee:'所有员工的基类'empCount=0def__init__(self,name,salary):self.name=nameself.salary=salaryEmployee.empCount+=1defdisplayCount(self):print("Total Employee %d"%Employee.empCount)defdisplayEmployee(self):print("Name : ",self.name,", Salary: ",self.salary)
empCount 变量是一个类变量,它的值将在这个类的所有实例之间共享。你可以在内部类或外部类使用 Employee.empCount 访问。
第一种方法init()方法是一种特殊的方法,被称为类的构造函数或初始化方法,当创建了这个类的实例时就会调用该方法
self 代表类的实例,self 在定义类的方法时是必须有的,虽然在调用时不必传入相应的参数。
self代表类的实例,而非类
类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称是 self。
classTest:defprt(self):print(self)print(self.__class__)t=Test()t.prt()
以上实例执行结果为:
<__main__.Test instance at 0x10d066878>__main__.Test
从执行结果可以很明显的看出,self 代表的是类的实例,代表当前对象的地址,而self.class则指向类。
self 不是 python 关键字,我们把他换成 runoob 也是可以正常执行的:
实例
classTest:defprt(runoob):print(runoob)print(runoob.__class__)t=Test()t.prt()
以上实例执行结果为:
<__main__.Test instance at 0x10d066878>__main__.Test
创建实例对象
实例化类其他编程语言中一般用关键字 new,但是在 Python 中并没有这个关键字,类的实例化类似函数调用方式。
以下使用类的名称 Employee 来实例化,并通过init方法接收参数。
"创建 Employee 类的第一个对象"emp1 = Employee("Zara", 2000)"创建 Employee 类的第二个对象"emp2 = Employee("Manni", 5000)
访问属性
您可以使用点号.来访问对象的属性。使用如下类的名称访问类变量:
emp1.displayEmployee()emp2.displayEmployee()print"Total Employee %d"% Employee.empCount
完整实例:
实例
#!/usr/bin/python# -*- coding: UTF-8 -*-classEmployee:'所有员工的基类'empCount=0def__init__(self,name,salary):self.name=nameself.salary=salaryEmployee.empCount+=1defdisplayCount(self):print("Total Employee %d"%Employee.empCount)defdisplayEmployee(self):print("Name : ",self.name,", Salary: ",self.salary)"创建 Employee 类的第一个对象"emp1=Employee("Zara",2000)"创建 Employee 类的第二个对象"emp2=Employee("Manni",5000)emp1.displayEmployee()emp2.displayEmployee()print("Total Employee %d"%Employee.empCount)
执行以上代码输出结果如下:
Name : Zara ,Salary: 2000Name : Manni ,Salary: 5000Total Employee 2
你可以添加,删除,修改类的属性,如下所示:
emp1.age=7# 添加一个 'age' 属性emp1.age=8# 修改 'age' 属性delemp1.age# 删除 'age' 属性
你也可以使用以下函数的方式来访问属性:
getattr(obj, name[, default]) : 访问对象的属性。
hasattr(obj,name) : 检查是否存在一个属性。
setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性。
delattr(obj, name) : 删除属性。
hasattr(emp1, 'age') # 如果存在 'age' 属性返回 True。getattr(emp1, 'age') # 返回 'age' 属性的值 setattr(emp1, 'age', 8) # 添加属性 'age' 值为 8 delattr(emp1, 'age') # 删除属性 'age'
Python内置类属性
dict: 类的属性(包含一个字典,由类的数据属性组成)
doc:类的文档字符串
name: 类名
module: 类定义所在的模块(类的全名是'main.className',如果类位于一个导入模块mymod中,那么className.module等于 mymod)
bases: 类的所有父类构成元素(包含了一个由所有父类组成的元组)
Python内置类属性调用实例如下:
实例
#!/usr/bin/python# -- coding: UTF-8 --classEmployee:'所有员工的基类'empCount=0definit(self,name,salary):self.name=name self.salary=salary Employee.empCount+=1defdisplayCount(self):print("Total Employee % d"%Employee.empCount)defdisplayEmployee(self):print("Name : ",self.name,", Salary: ",self.salary)print("Employee.doc:",Employee.__doc__)print("Employee.name:",Employee.__name__)print("Employee.module:",Employee.__module__)print("Employee.bases:",Employee.__bases__)print("Employee.dict:",Employee.__dict__)
执行以上代码输出结果如下:
Employee.__doc__: 所有员工的基类Employee.__name__: EmployeeEmployee.__module__: __main__Employee.__bases__: ()Employee.__dict__: {'__module__': '__main__', 'displayCount': , 'empCount': 0, 'displayEmployee': , '__doc__': '\xe6\x89\x80\xe6\x9c\x89\xe5\x91\x98\xe5\xb7\xa5\xe7\x9a\x84\xe5\x9f\xba\xe7\xb1\xbb', '__init__': }
python对象销毁(垃圾回收)
Python 使用了引用计数这一简单技术来跟踪和回收垃圾。
在 Python 内部记录着所有使用中的对象各有多少引用。
一个内部跟踪变量,称为一个引用计数器。
当对象被创建时, 就创建了一个引用计数, 当这个对象不再需要时, 也就是说, 这个对象的引用计数变为0 时, 它被垃圾回收。但是回收不是"立即"的, 由解释器在适当的时机,将垃圾对象占用的内存空间回收。
a=40# 创建对象<40>b=a # 增加引用,<40>的计数c=[b]# 增加引用.<40>的计数del a # 减少引用<40>的计数b=100# 减少引用<40>的计数c[0]=-1# 减少引用<40>的计数
垃圾回收机制不仅针对引用计数为0的对象,同样也可以处理循环引用的情况。循环引用指的是,两个对象相互引用,但是没有其他变量引用他们。这种情况下,仅使用引用计数是不够的。Python 的垃圾收集器实际上是一个引用计数器和一个循环垃圾收集器。作为引用计数的补充, 垃圾收集器也会留心被分配的总量很大(即未通过引用计数销毁的那些)的对象。 在这种情况下, 解释器会暂停下来, 试图清理所有未引用的循环。
实例
析构函数del,del在对象销毁的时候被调用,当对象不再被使用时,del方法运行:
#!/usr/bin/python# -- coding: UTF-8 --classPoint:definit(self,x=0,y=0):self.x=x self.y=ydef__del__(self):class_name=self.__class__.__name__print(class_name,"销毁")pt1=Point()pt2=pt1pt3=pt1printid(pt1),id(pt2),id(pt3)# 打印对象的iddelpt1delpt2delpt3
以上实例运行结果如下:
3083401324 3083401324 3083401324Point 销毁
注意:通常你需要在单独的文件中定义一个类,
类的继承
面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。
通过继承创建的新类称为子类或派生类,被继承的类称为基类、父类或超类。
继承语法
class派生类名(基类名)...
在python中继承中的一些特点:
1、如果在子类中需要父类的构造方法就需要显式的调用父类的构造方法,或者不重写父类的构造方法。详细说明可查看: python 子类继承父类构造函数说明。
2、在调用基类的方法时,需要加上基类的类名前缀,且需要带上 self 参数变量。区别在于类中调用普通函数时并不需要带上 self 参数
3、Python 总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。
如果在继承元组中列了一个以上的类,那么它就被称作"多重继承" 。
语法:
派生类的声明,与他们的父类类似,继承的基类列表跟在类名之后,如下所示:
classSubClassName(ParentClass1[,ParentClass2,...]):...
实例
classParent:# 定义父类parentAttr=100def__init__(self):print("我是父类构造函数")defparentMethod(self):print("调用父类方法")defsetAttr(self,arrt):Parent.parentAttr=arrtdefgetAttr(self):print("父类属性:",Parent.parentAttr)classChild(Parent):# 定义子类def__init__(self):print("调用子类构造方法")defchildMethod(self):print("调用子类方child method")c=Child()c.childMethod()c.parentMethod()c.setAttr(200)c.getAttr()
以上代码执行结果如下:
调用子类构造方法调用子类方法调用父类方法父类属性 : 200
你可以继承多个类
classA:# 定义类 A.....classB:# 定义类 B.....classC(A,B):# 继承类 A 和 B.....
你可以使用issubclass()或者isinstance()方法来检测。
issubclass() - 布尔函数判断一个类是另一个类的子类或者子孙类,语法:issubclass(sub,sup)
isinstance(obj, Class) 布尔函数如果obj是Class类的实例对象或者是一个Class子类的实例对象则返回true。
方法重写
如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法:
实例:
实例
classAnimal:# 定义父类defrun(self):print("Animal is running...")# 调用父类方法classCat(Animal):# 定义子类defrun(self):print("Cat is running....")# 调用子类方法classDog(Animal):# 定义子类defrun(self):print("Dog is running.....")# 调用子类方法c=Dog()# 子类实例c.run()
执行以上代码输出结果如下:
Dogisrunning.....
基础重载方法
下表列出了一些通用的功能,你可以在自己的类重写:
序号方法, 描述 & 简单的调用
1init ( self [,args...] )构造函数 简单的调用方法:obj = className(args)
2del( self )析构方法, 删除一个对象 简单的调用方法 :del obj
3repr( self )转化为供解释器读取的形式 简单的调用方法 :repr(obj)
4str( self )用于将值转化为适于人阅读的形式 简单的调用方法 :str(obj)
5cmp ( self, x )对象比较 简单的调用方法 :cmp(obj, x)
运算符重载
Python同样支持运算符重载,实例如下:
实例
#!/usr/bin/pythonclassVector:def__init__(self,a,b):self.a=aself.b=bdef__str__(self):return'Vector (%d, %d)'%(self.a,self.b)def__add__(self,other):returnVector(self.a+other.a,self.b+other.b)v1=Vector(2,10)v2=Vector(5,-2)print(v1+v2)
以上代码执行结果如下所示:
Vector(7,8)
类属性与方法
类的私有属性
__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时self.__private_attrs。
类的方法
在类的内部,使用def关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数
类的私有方法
__private_method:两个下划线开头,声明该方法为私有方法,不能在类的外部调用。在类的内部调用self.__private_methods
实例
# !/usr/bin/python # -*- coding: UTF-8 -*-classJustCounter:__secretCount=0# 私有变量publicCount=0# 公开变量defcount(self):self.__secretCount+=1self.publicCount+=1print(self.__secretCount)counter=JustCounter()counter.count()counter.count()print(counter.publicCount)print(counter.__secretCount)# 报错,实例不能访问私有变量
Python 通过改变名称来包含类名:
122Traceback(most recent call last):File"test.py",line17,in<module>print counter.__secretCount# 报错,实例不能访问私有变量AttributeError:JustCounterinstance has no attribute'__secretCount'
Python不允许实例化的类访问私有数据,但你可以使用object._className__attrName(对象名.类名_私有属性名)访问属性,参考以下实例:
#!/usr/bin/python# -*- coding: UTF-8 -*-classRunoob:__site="www.runoob.com"runoob=Runoob()printrunoob._Runoob__site
执行以上代码,执行结果如下:
www.runoob.com
单下划线、双下划线、头尾双下划线说明:
foo: 定义的是特殊方法,一般是系统定义名字 ,类似init()之类的。
_foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于from module import *
__foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了。