Print函数
print('hello world')
#print('hello world')
print(520)
print(95.2)
print(3+1)
print可以将输出的值保存到文件当中去,因为print中有file这个属性,所以可以将输出的值输出到file里面,而不用输出到显示屏上
fp=open('./text.txt','a+')
print('hello world',file=fp)
fp.close()
print输出之后会自动换行的,所以如果你想要不换行的话,得需要在一个print里面输出所有东西
print('hello','world')
转义字符
\n:换行
print('hello\nworld')
\r:回车
print('helloooo\rworld')
\b:代表退格,往前删一个单元,相当于backspace
print('hello\bworld')
print('helloo\bworld')
\t:就代表tab,一般是以四个字符为一个单元的,缺几个补几个,不缺的话,就写四个
print('hell\tworld')
print('hello\tworld')
print('helloo\tworld')
print('hellooo\tworld')
:在字符串里面,如果你想用\的话,就得使用转义字符\,一个\需要一个转义,两个杠就需要两个\
print('http:\\www.baidu.com') #仅仅只是用来举例,不表示正确的网址,正确的网址下面应该是//,不是\\
print('http:\\\\www.baidu.com')
‘:在字符串里面,如果需要使用‘的话,需要加上转义字符
print('http:\\www.baidu.com') #仅仅只是用来举例,不表示正确的网址,正确的网址下面应该是//,不是\\
print('http:\\\\www.baidu.com')
‘r’:是防止字符转义的 如果路径中出现’\t’的话 不加r的话\t就会被转义 而加了’r’之后’\t’就能保留原有的样子
在字符串赋值的时候 前面加’r’可以防止字符串在时候的时候不被转义 原理是在转义字符前加’’
print(r'http:\\\\www.baidu.com')
#print(r'http:\\\\www.baidu.com\') 因为这个字符串末尾是\,所以这句话是错误的,结尾不能是\
print(r'http:\\\\www.baidu.com\\')
二进制与字符编码
主要有ascll编码和GBK编码,有什么utf-8编码和unicode编码,这四种编码的区别和目的如下
acsll编码使用128个字符来表示英文的常见字符,无法表示汉字或者其他国家的语言,中国就搞了自己的国家的GBK编码,用来表示中国的常用字符,但是GBK包含的字符不全,中国后来有引入了GB18030来表示更多的中国字符,Unicode是为了解析各个国家的编码的不同,而设定的一个规定的标准,但是这个标准又不太好,因为他规定了所有字符都是两个字节来解析的,这样就会很慢,所以有引入了什么utf-8这种标准,让英文一个字节来解析,中文三个字节来解析,来帮助Unicode这种标准,一般情况下,如果不指定编码的话,都是默认unicode
标识符和关键字
1.python的标识符命名规则和C一样,可一起记忆
2.如何查看python中的关键字?
import keyword
print(keyword.kwlist)
变量
变量有三部分组成:变量名,运算表达式,值
name='楚留香'
print(name,id(name))
print(name,type(name))
print(name)
name里面其实保存的是id值,这个id值同时保存在name和’楚留香‘这两个里面,是相同的,当print(name)的时候,会从name里面id对应的值找到‘’楚留香,然后输出,一般情况下,只会有id,类型,还有值保存在你命名的变量内存里面。变量名相当于指针,多次赋值的话,指针对应的id值会变,就会指向不同的value对应的id值
name='楚留香'
name='张三'
print(name,id(name))
print(name,type(name))
print(name)
数据类型
1.整型:int
2.浮点型:float
使用浮点型的变量相加之后可能会存在值不准确的问题,可以考虑引入decimal模块,decimal其实也是一种数据类型,是十进制的数据类型,实际上就是将flaot类型进行一次强制类型转换,不让他变成浮点数相加,就不会产生浮点数相加的误差。
对于decimal模块而言,可以使用其自带的getcontext().prec这个属性来改变其精度。假设精度为1,相当于只有一个数字,依次类推,他的默认精度是28位。
他和浮点数类型的区别就在于他更加精确,所以当你需要表示的数很精确的时候,必须采用decimal,浮点数随便可以 表示的数的范围很大,但是不太精确,都是近似的,所以一般用decimal表示精确的值
import decimal
decimal.getcontext().prec=28
n1=1.1
print(n1,type(n1))
n2=2.2
print(n1+n2)
#print(Decimal('n1')+Decimal('n2')) 这样是不行的,因为他是数据类型,你不可以吧变量名放进去让他类型转换,你只可以放变量的值进去进行类型转换
print(decimal.Decimal('1.1')+decimal.Decimal('2.2'))
print(decimal.getcontext().prec)
m1=decimal.Decimal('1.1')
m2=decimal.Decimal('2.2')
print(m1+m2)
3.布尔类型:
就是只有两个值:true和false
和其他语言不同的是,它可以直接被当成整型来计算,True默认为1,False默认为0,因为python严格区分大小写,所以true的T必须是大写,false的F也必须是大写
m1=True
m2=False
print(m1,type(m1))
print(m2,type(m2))
print(m1+1) #结果是2
print(m2-1) #结果是-1
4.str数据类型
字符串定义可以使用单引号,可以使用双引号,也可以使用三引号,三引号和其他引号不同的是,他的字符串的值可以分布在两行输入或者显示
str1='人生苦短,我用python'
str2="人生苦短,我用python"
str3='''人生苦短,我用python'''
str4="""人生苦短,我用python"""
str5='''人生苦短,
我用python'''
str6=""""人生苦短,
我用python
"""
print(str1)
print(str2)
print(str3)
print(str4)
print(str5)
print(str6)
5.str类型转换
一般是用在连接符的情况下,因为连接符要求连接前后的数据类型必须一致,所以采用类型转换。
name='张三'
age=20
#print('我的名字是:'+name+',我的年龄是多大:'+age) #因为连接符前后数据类型不一样,所以报错
print('我的名字是'+name+',我的年龄是:'+str(age))
6.int类型转换
一般只能转换字符串类型为整数的值,和浮点数转换的时候需要舍去小数,在转换布尔类型的时候,可以正常转换
s1='98'
s2='98.8'
s3='tom'
f1=98.8
b1=True
b2=False
print(s1,s2,s3,f1,b1,b2)
print(int(s1))
#print(int(s2)) 不是整型,不能转换
print(int(s3)) 不是整型,不能转换
print(int(f1)) #转完之后直接取整
print(int(b1))
print(int(b2))
7. 浮点数类型转换:float()
可以将除了字符串为文字的部分无法转外,其他都可以转换,另外,当转换的值为整数的时候,会自动补零,不管这个整数是什么类型的
s1='1980'
s2='198.59'
s3='hello'
i1=95
b1=True
b2=False
print(float(s1)) #他转换为1980.0,因为是整数,所以带0
print(float(s2)) #转换为198.59
#print(float(s3)) #无法转换,因为是文字
print(float(i1)) #他转换为95.0,因为是整数,所以带0
print(float(b1)) #他转换为1.0,因为是整数,所以带0
print(float(b2)) #他转换为0.0,因为是整数,所以带0
8.注释方式
- 第一种就是很常见的#来注释
- 第二种就是三引号来注释,三引号表示的字符串可以换行
''''嘿嘿嘿,
我是一个
注释哦
'''
- 在python编写代码的时候,避免不了会出现或是用到中文,这时候你需要在文件开头加上中文注释。比如创建一个python list,在代码上面注释上它的用途,如果开头不声明保存编码的格式是什么,那么它会默认使用ASKII码保存文件,这时如果你的代码中有中文就会出错了,即使你的中文是包含在注释里面的。所以加上中文注释很重要。
#coding:utf-8
print('hello world')
input函数
他的返回值类型一定是str类型
m1=input('please input the first word:')
m2=input('please input the second word:')
print(int(m1)+int(m2))
运算符
赋值运算符
它支持四种运算:
1.支持连续赋值,就是连续等于,例如
a=b=c=20
2.支持参数赋值
m=20
print(m)
m+=10 #30
print(m)
m-=10 #20
print(m)
m*=3 #60
print(m)
m/=5 #12
print(m)
m//=2 #6
print(m)
m%=2 #0
print(m)
3.支持系列解包赋值,实际上就是类似这样可以直接给多个变量赋值,等号左边和右边的数量应该相同
一般用于交换两个变量的值
o,p,q=10,20,30
print(o,p,q)
o,q,p=10,20,30
print(o,p,q)
算数运算符
加:+
减:-
乘:*
除:/
幂次方:****,比如2的三次幂,就是2**3
整除://,比如8//3=2,但是有特殊情况,当整除的被除数和除数符号不相同时,结果向下取整
#取余:%,有特殊情况,当取余的被除数和除数符号不相同的情况下,余数=被除数-商乘以除数
print(1+1) #输出2
print(1-8) #输出-7
print(1*8) #输出8
print(1**8) #输出1
print(2**5) #输出32
print(9/4) #输出2.25
print(9/(-4)) #输出-2.25
print(9//4) #输出2
print(9//(-4)) #输出-3
print(9%4) #1
print((13%(-5))) #-2
print((-13)%5) #2
比较运算符
大于:>
小于:<
等于:==
大于等于:>=
小于等于:<=
不等于:!=
is :比较的是两个实例对象是不是完全相同,它们是不是同一个对象,占用的内存地址是否相同。即is比较两个条件:1.内容相同。2.内存中地址相同
使用is注意python对于小整数使用对象池存储问题
1.举个例子,在python命令行模式下:为什么同样值a,b与c,d的结果却不一样呢?
>>> a = 1000
>>> b = 1000
>>> a is b
False
>>> c = 10
>>> d = 10
>>> c is d
True
注意,因为python对小整数在内存中直接创建了一份,不会回收,所有创建的小整数变量直接从对象池中引用他即可。
但是注意Python仅仅对比较小的整数对象进行缓存(范围为范围[-5, 256])缓存起来,而并非是所有整数对象。
也就说只有在这个[-5,256]范围内创建的变量值使用is比较时候才会成立。
>>> e ,d ,f ,g = -5 ,-5 ,-6 ,-6
>>> e is d
True
>>> f is g #超过-5的范围不成立
False
>>>
布尔运算符
并且:and:
或者:or:
相反:not:是针对布尔类型的操作数取反
in :可以用来检查某个字符是否在这个字符串里面
not in:可以用来检查某个字符没有在这个字符串里面
!!!!!!!!!!!!!布尔运算符一般也是对布尔类型操作数进行运算的
a=1
b=2
print(a==1 and b==2)
print(a<1 and b<2)
print(a==1 and b<2)
print(a!=1 and b==2)
print(a==1 or b==2)
print(a<1 or b<2)
t=True
f=False
print(not t)
print(not f)
m='hello world'
print('h' in m)
print('h' not in m)
print('h' in 'hello')
位运算
#按位与&:就是让a&b。让a的每一位与b的每一位进行与运算,得到的值为按位与后的值
#按位或|:就是a|b。让a的每一位与b的每一位进行或运算,得到的值为按位或后的值
左移运算符:就是a<<1,相当于a左移一位,相当于a乘以2
右移运算符:就是a>>1,相当于a右移一位,相当于a除以2
print(4&8) #结果为0
print(4&12) #结果为4
print(8&9) #结果为8
print(4|8) #结果为12
print(4|12) #结果为12
print(8|9) #结果为9
print(4<<2) #结果为16
print(4>>2) #结果为1
运算符的优先级
优先级最最高的是括号
优先级最高的是算数运算符,算数运算符里面,要先算幂运算,再算乘除,再算加减
过来是位运算符,先做左移右移,再算按位或,按位与,
再然后是比较运算符,把算得的结果是true或者false送给布尔运算符
最后是布尔运算符
程序的结构
顺序结构
什么是顺序结构呢?比如说
'''把大象装冰箱需要分几步?'''
print('----------------------程序开始')
print('1.打开冰箱')
print('2.把大象放进去')
print('3.关闭冰箱')
print('-------------------------程序结束')
分支结构
单分支结构
'''就比如从银行取钱'''
money=10000
get=int(input('请输入您要取的金额:'))
if get<money:
money=money-get
print('恭喜你,取钱成功,剩余金额为:',money)
双分支结构
相当于一个分岔口,有两条路可以选择,你可以走其中一条
'''从键盘录入一个数字,判断该数字是奇数还是偶数,并且输出'''
a=int(input('请输入你想要查询的数字:'))
if a%2:
print(a,',他是一个奇数')
else:
print(a,',他是一个偶数')
多分支结构
多分支结构里面,一般使用elif来代替C语言里面的else if
最后的一个else是可以省略的,即分支结构里面可以全是elif,elif后面必须加入判断语句
num=int(input('请输入你要查询的分数:'))
if num >= 90 and num <=100:
print("成绩是在90分以上")
elif num>=80 and num <90 :
print('成绩是在80分以上')
elif num>=70 and num <80:
print('成绩在70分以上')
elif num >=60 and num <70:
print('成绩在60分以上')
elif num<60 and num >=0:
print('你没有及格哦')
else:
print('对不起.输入有误')
当然,除了上面这种写法之外,还有一种写法,就是python语言特有的写法,就是可以把这种and连接的判断语句并到一起,修改之后如下
num=int(input('请输入你要查询的分数:'))
if 90<=num <=100:
print("成绩是在90分以上")
elif 80<=num <90 :
print('成绩是在80分以上')
elif 70<=num <80:
print('成绩在70分以上')
elif 60<=num <70:
print('成绩在60分以上')
elif 60>=num>=0:
print('你没有及格哦')
else:
print('对不起.输入有误')
嵌套if的使用
就是在一个if的下面再写一个if,在运行的时候,会层层判断进去,直到找到你所要符合的条件
'''判断是否为会员,会员与非会员之间有大的折扣差别
是会员的话,如果购买金额大于200,打八折,大于100,打9折,否则不打折.
非会员的话,大于200打9.5折,其余不打折'''
import decimal
decimal.getcontext().prec=9
a=input('请问你是会员吗?(y/n):')
b=decimal.Decimal(input('请输入你购买的金额:'))
if a=='y':
if b>=200:
print('本次消费:',b*decimal.Decimal(0.8))
elif 100<=b<200:
print('本次消费:',b*decimal.Decimal(0.9))
else:
print('本次消费',b)
else:
if b>=200:
print('本次消费:',b*decimal.Decimal(0.95))
else:
print('本次消费',b)
’------------------------还有一种实现方法-------------------------'
a=input('请问你是会员吗?(y/n):')
b=float(input('请输入你购买的金额:'))
if a in'y':
if b>=200:
print('本次消费:',b*0.8)
elif 100<=b<200:
print('本次消费:',b*.9)
else:
print('本次消费',b)
else:
if b>=200:
print('本次消费:',b*0.95)
else:
print('本次消费',b)
条件表达式
语法格式如下:
x if 判断语句 else y
如果判断语句为真,则执行X语句,如果判断语句为假,则执行y语句,条件表达式中间没有任何逗号或者冒号
m=1 if 3<=2 else 2
print(m)
a=int(input('请输入第一个数:'))
b=int(input('请输入第二个数:'))
'''n=a if a>=b else b
print(n)'''
print(a if a>=b else b)
pass语句
如果定义一个空函数程序会报错,当你没有想好函数的内容是可以用 pass 填充,使程序可以正常运行。
m=int(input('请输入第一个数:'))
n=int(input('请输入第二个数:'))
if m>n:
pass
else:
pass
range函数
这个函数生成的是一个整数序列,他的返回值是一个迭代器对象,所以直接print它是没有用的,输出不了里面的值
所以要看它里面的值的话,得把他列表化,然后print才可以打印出来
书写方式
1.如果只写一个参数,那么就默认这个参数是终止值,他的起始值默认是0,他的步长默认是1,就会产生一个以0开始,到终止值-1且步长为1的列表序列
a=range(20)
print(a) #输出range(0, 20)
print(list(a)) #输出[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
2.如果只写两个参数,那么这两个参数的第一个默认为起始值,第二个数默认为终止值,步长还是默认为1,会产生以第一个数为起始值,第二个数为终止值的步长为1的列表序列
a=range(10,20)
print(list(a)) #输出[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
3.如果写三个参数,那么这三个参数中第一个参数默认为起始值,第二个参数默认为终止值,第三个参数默认为步长,他就会产生以第一个数为起始值,第二个数为终止值,第三个数为步长的列表序列
a=range(10,20,3)
print(list(a)) #输出[10, 13, 16, 19]
4.一般用in 或者not in来判断在range生成的序列里面有没有这个数
print(10 in list(a)) #输出为True
print(15 in list(a)) #输出为False
print(10 in a) #输出为True,相当于使用了这个函数,所以就会计算这个函数,所以才会使True
print(1 in a) #输出为True
while循环
while的具体用法和C一样,无出其右罢了,下面只有几个代码示例
'''计算0到4的和'''
b=0
a=0
while a<=4:
b=b+a
a=a+1
print(b)
'''计算1-100之间的偶数和'''
'''sum=0
a=0
while a<=100:
sum=sum+a
a+=2
print('1-00之间的偶数和为:',sum)'''
sum=0
a=0
while a<=100:
if not bool(a%2): #bool将得到的对象强制转换成布尔类型True或者False
sum = sum + a
a+= 1
print('1-00之间的偶数和为:',sum)
for item in 迭代对象
首先它会将迭代对象的值赋值给item,然后执行次数就是迭代对象的迭代次数,迭代对象是个集合
如果你不需要使用item,可以将其替换成_,这样,你就相当于只是使用了迭代次数.
'''sum=0
for i in range(0,101,2):
sum+=i
print(sum)'''
sum=0
for i in range(101):
if not i%2:
sum+=i
print(sum)
比如:求出100-999之间所有的水仙花数
在写水仙花数的时候,一定需要注意一点,python里面的/表示除法,不是整除,不能惯用C语言的知识去写
'''import decimal
for item in range(100,1000):
m=item
a=decimal.Decimal(item)%decimal.Decimal(10)
item=decimal.Decimal(item)//decimal.Decimal(10)
b=decimal.Decimal(item)%decimal.Decimal(10)
c=decimal.Decimal(item)//decimal.Decimal(10)
if a**3+b**3+c**3==m:
print(m)'''
print('--------------其实没有必要写decimal的类型')
for item in range(100, 1000):
m = item
a = item %10
item = item//10
b = item % 10
c = item // 10
if a ** 3 + b ** 3 + c ** 3 == m:
print(m)
break
是用来结束循环的一个语句,一般只用在循环结构中,分支和选择结构中,不用break
他只负责控制自己所在的循环,如果在多重循环中,他只负责结束自己循环的部分,不结束外层循环
'''输入密码,输入正确立即退出,输入错误,可以尝试三次'''
print('------------for_in---------------')
for item in range(3):
pwd=input('请输入你的密码:')
if pwd =='8888':
print('密码正确')
break
else:
print('密码错误,请重新输入,你还可剩余输入密码次数:',2-item)
print('-----------while-------------------------')
a=0
while a<3:
pwd = input('请输入你的密码:')
if pwd == '8888':
print('密码正确')
break
else:
print('密码错误,请重新输入,你还可剩余输入密码次数:', 2 - a)
a+=1
print('-----多层循环中,breake值结束自己循环的当前循环------------------------------------------')
for i in range(3):
for j in range(5):
if not j%2: #0%2的值为0,not之后变成了1,然后打印出了0
print(j,end='\t') #输出三行0
break
print()
continue
它的作用是立即跳出当前循环,进入下一循环
他只负责控制自己所在的循环,如果在多重循环中,他只负责结束自己循环的部分,不结束外层循环
""""输出1-50之间所有5的倍数"""
for item in range(1,51):
if not item%5:
print(item)
print('--------使用continue表示-----------------------')
for item in range(1,51):
if item%5:
continue
print(item)
print('-----多层循环中,continue值结束自己循环的当前循环------------------------------------------')
for i in range(3):
for j in range(5):
if not j%2:
print(j,end='\t')
continue
print()
else语句
有三种搭配方式
1.和if搭配:和if搭配的时候,if语句或者else语句只执行其一即可
2.和while搭配:如果while语句执行完的时候,没有出现break,则执行else,如果出现break,则不执行else
3.和for搭配:和while搭配同理
for item in range(3):
pwd=input('请输入密码:')
if pwd=='8888':
print('密码正确')
break
else:
print('密码错误.')
else:
print('已经输入密码错误三次,请过90S之后再次尝试')
print('-------和while搭配-------------------')
a=0
while a<3:
pwd = input('请输入密码:')
if pwd == '8888':
print('密码正确')
break
else:
print('密码错误.')
a+=1
else:
print('已经输入密码错误三次,请过90S之后再次尝试')
循环嵌套
这个模块有三个实例
'''输出一个三行四列的矩形'''
#在print函数里面,end参数表示的是输出完成之后该做什么,默认情况下,end='\n',如果要求不换行的话,可以设置end=''或者end='\t'
for item in range(3):
for item1 in range(4):
print('*',end='\t')
print('')
'''输出一个直角三角形,最后一行是9个*'''
for i in range(9):
for j in range(1,10):
if j-i<=1:
print('*', end='')
print('')
for i in range(1,10):
for j in range(0,i):
print('*', end='')
print('')
'''输出一个9*9乘法表'''
for i in range(1,10):
for j in range(1,10):
if i>=j:
print(i, '*', j, '=', i * j, end='\t')
print('')
for i in range(1,10):
for j in range(0,i):
print(i, '*', j+1, '=', i * (j+1), end='\t')
print('')
列表
为什么要使用列表?
列表就好比C语言中的数组,它可以在这个数组里面保存各种类型的数据,保存的数据更多,所以引入列表,来帮助变量只能保存一个数值的尴尬境地
a=['hello','world',95,98.5]
print(a)
在这个代码里面,list是列表名,保存的id值,然后这个id值可以指向保存里面三个数据的id值,三个数据的id值指向具体数值
列表的初始化
有两种方法:
1.直接使用[],在[]里面写入列表
b=['hello','world',95,98.5]
print(b)
2.使用内置函数list(),在()里面加入[],创建列表,可以用在将range函数转换为列表
list2=list(['sad','sadsa'])
print(list2)
list3=list(range(100))
print(list3)
#list2=list(['sad','sadsa'],['sad','dsad']) 不能在里面创建多个列表的
列表的特点
1.可以存储相同的元素
m=[98,98,98,'dsa']
print(m)
2.可以通过索引指定元素,从左到右的话,从0开始计数,从右到左的话,从-1开始计数,总之,列表中元素的个数等于从左到右的计数+从右到左的绝对值的和
m=['asdsa','sdadsa','qwewqe']
print(m[1],m[-2]) #会输出同一个值
3.可以存取任意数据类型的数据
获取列表指定元素的索引值
index(),获取列表指定元素的索引值,是通过list的index方法来获取的.
index方法使用有以下三个注意点:
1.index只会返回寻找到第一个的索引值,所以如果列表中有重复元素,index也只会返回第一个
list1=['hello','adasd','dsadsa','zxcxzc','hello']
print(list1.index('hello')) #输出为0 #虽然list1列表中有两个hello值,但是只会返回第一个找到的索引值,所以输出为0
2.如果index找不到指定元素,会报错的
list3=['cx','dsa',9800]
print(list3.index('hello')) #输出:ValueError: 'hello' is not in list,这个属于报错,会导致下面的代码无法正常执行
3.index方法可以指定寻找的序列,index(‘要寻找的值’,x,y),x表示开始寻找的序列,y表示结束寻找的序列
list4=['sadad','xzc','qewqe','yiuy']
print(list4.index('qewqe',0,3)) #输出结果为1
获取列表中的单个元素
1.可以正向获取,也可以逆向获取,正向获取的时候,从0开始计数,逆向获取的时候,从-N开始计数
2.如果获取的索引值超过列表的范围,就会报错
li=['xcz','sadas','xzxz','wqqww']
print(li[1]) #输出第二个数据
print(li[-1]) #输出最后一个数据
# print(li[6]) 超出列表的范围,所以报错
获取列表的多个元素
获取多个元素采用切片法,语法格式如下:
列表名[start:stop:step]
切片获取的列表为一个新的列表,因为他和旧的列表的id值是不相同的
lis=[0,1,2,3,4,5,6,7]
print(id(lis),lis)
lis1=lis[2:6:1]
print(id(lis1),lis1)
总共会有以下几种场景使用:
1.正常操作
list1=[0,10,20,30,40,50,60,70,80,90]
print(list1[0:7:1]) #会输出[0, 10, 20, 30, 40, 50, 60]
print(list1[0:7:3]) #输出[0, 30, 60]
2.省略起始值.
省略初始值时,会默认初始值为0
print(list1[:7:1]) #输出[0, 10, 20, 30, 40, 50, 60]
3.省略终止值
省略终止值时,会默认终止值为最后一个数值
print(list1[1::1]) #输出[10, 20, 30, 40, 50, 60, 70, 80, 90]
4.省略步长
省略步长时,默认步长为1
print(list1[1:7:]) #输出[10, 20, 30, 40, 50, 60]
5.当步长为负数时
步长为负数时,可以理解为从起始值的位置开始减,一直减到终止值位置
print(list1[6:2:-1]) #输出[60, 50, 40, 30]
一般情况下,列表逆序输出的时候,都是采用步长为负数进行输出
print(list1[::-1]) #输出[90, 80, 70, 60, 50, 40, 30, 20, 10, 0]
列表元素的遍历
采用for in循环:
lis=[1,213,5.5,'sagdja','adsasd']
for item in lis:
print(item)
列表元素的判断
in 或者 not in
lis=[1,213,5.5,'sagdja','adsasd']
print('www' in lis)
print(1 in lis)
print('www' not in lis)
print(1 not in lis)
列表的添加操作
列表的添加元素有四种方法:
列表的添加操作不改变列表的id值,所以相当于没有新的列表产生
比较常用的是append,四种方法包括append,extend,insert以及切片法
append
将需要添加的元素填充到列表的末尾,只允许添加一个元素,如果这个元素是一个列表.会把这个元素当成一个列表,然后全部插入
lis=['zxZ','dwq','wqe','zxc','wr','cfwf']
lis.append(95)
print(lis) #输出['zxZ', 'dwq', 'wqe', 'zxc', 'wr', 'cfwf', 95]
lis2=[1,2,3,4]
lis.append(lis2)
print(lis) #输出['zxZ', 'dwq', 'wqe', 'zxc', 'wr', 'cfwf', 95, [1, 2, 3, 4]]
extend
可以在末尾添加多个元素,是append的补充,比如在下面的lis1里面插入lis2,不会把lis2整体插入,会把里面的元素取出来,然后插入
lis1=['zxZ','dwq','wqe','zxc','wr','cfwf']
lis2=[1,2,3,4]
lis1.extend(lis2)
print(lis1) #输出['zxZ', 'dwq', 'wqe', 'zxc', 'wr', 'cfwf', 1, 2, 3, 4]
insert
可以在列表中的任意位置插入元素,但是只能插入一个,语法格式如下
列表名.insert(索引值,插入的元素),表示在索引值-----前面----插入元素
lis1=['zxZ','dwq','wqe','zxc','wr','cfwf']
lis2=[1,2,3,4]
lis1.insert(1,lis2)
print(lis1) #输出结果['zxZ', [1, 2, 3, 4], 'dwq', 'wqe', 'zxc', 'wr', 'cfwf']
lis1.insert(0,98)
print(lis1) #在索引值前面插入字符 [98, 'zxZ', [1, 2, 3, 4], 'dwq', 'wqe', 'zxc', 'wr', 'cfwf']
片选插入
可以在列表的任意位置后面,插入多个元素,相当于切掉这个切片的元素值,改用新的元素代替
lis1=['zxZ','dwq','wqe','zxc','wr','cfwf']
lis2=[1,2,3,4]
lis1[1:4:]=lis2
print(lis1) #输出['zxZ', 1, 2, 3, 4, 'wr', 'cfwf']
lis1[1::]=[1,2]
print(lis1) #输出['zxZ', 1, 2]
列表中的删除操作
remove
移除这个元素不存在,这种情况会报错
'''lis=['sad','xzX','xzX','zxXZxxq']
lis.remove('qwe') #输出:ValueError: list.remove(x): x not in list
print(lis)'''
移除的这个元素在列表中有多个重复的,这种情况之会移除列表中第一个这个元素,不会移除所有的重复的
lis1=[1,5,6,8,9,7,5]
lis1.remove(5)
print(lis1) #输出[1, 6, 8, 9, 7, 5]
正常移除
lis2=['xczc','dqdc.','24r2x','asda',98]
lis2.remove(98)
print(lis2) #输出['xczc', 'dqdc.', '24r2x', 'asda']
pop()
pop方法也会有三种情况
索引值超出这个列表的范围
'''lis3=[1,2,3,5,7,9]
lis3.pop(8)
print(lis3) #输出IndexError: pop index out of range'''
不知道索引值的话,会默认删除列表的最后一个元素
lis4=[2,5,9,7,'fds']
lis4.pop()
print(lis4) #输出[2, 5, 9, 7]
正常移除
lis5=[5,9,'adasd','xZX','qwe']
lis5.pop(2)
print(lis5) #输出[5, 9, 'xZX', 'qwe']
切片删除
切片删除有两种情况,一种是把原列表的元素提取出来,组成一个新的列表,第二种情况是在原来的列表上面插入空的列表,就是用空的列表替换原来的列表
lis6=[5,9,9,7,2,3,8]
new_list=lis6[2:4]
print(new_list) #输出[9, 7]
lis7=[8,9,2,7,33,78,8]
lis7[2:4]=[]
print(lis7) #输出[8, 9, 33, 78, 8]
clear
指的是清空列表所有的元素,他就会变成一个空列表
lis8=[8,9,3,55,66,441.2,7]
lis8.clear() #语法格式如此
print(lis8) #输出[]
del
指的是直接删除这个列表变量,所以如果再打印这个变量的话,由于已经删除的关系,就会报错
'''lis9=[5,9651,25,456,879,4132,5641,7]
del lis9 #语法格式如此
print(lis9) #报错NameError: name 'lis9' is not defined'''
列表元素的修改操作
对单个元素直接修改
lis=[49,8,9,48,56,8,61,7]
print(lis) #输出[49, 8, 9, 48, 56, 8, 61, 7]
lis[5]=499
print(lis) #输出[49, 8, 9, 48, 56, 499, 61, 7]
切片修改
lis1=[789,56,46,5,8,4,65,465,46,64]
lis1[1:2]=['python','cxz','cxzcz']
print(lis1) #输出[789, 'python', 'cxz', 'cxzcz', 46, 5, 8, 4, 65, 465, 46, 64]
对列表的排序操作
有两种操作方法:
1.使用列表自有的sort()方法
2.使用内置函数sorted()方法
他俩之间的区别在于前者不会产生新的列表,而后者会产生新的列表
使用列表自有的sort()方法
该方法默认是升序排列,可以通过设置reverse的值为True是的其变成降序排列
list1=[6,451,5,456,4546,8,8,98,12,777]
list1.sort()
print(list1) #输出:[5, 6, 8, 8, 12, 98, 451, 456, 777, 4546]
list1.sort(reverse=True)
print(list1) #输出[4546, 777, 456, 451, 98, 12, 8, 8, 6, 5]
使用内置函数sorted()方法
该方法默认是升序排列,可以通过设置reverse的值为True是的其变成降序排列
list2=[48,915,312,5,8,123,56,123]
list3=sorted(list2)
print((list3)) #输出[5, 8, 48, 56, 123, 123, 312, 915]
list4=sorted(list3,reverse=True)
print(list4) #输出[915, 312, 123, 123, 56, 48, 8, 5]
列表生成式
list=[要存储的列表元素 for i/item in range(a,b)]
print('-----------生成一个含有2,4,6,8,10的列表-----')
li=[2*i for i in range(1,6)]
print(li)
m=list(range(1,10))
print(m)
字典
基础知识
可变序列:目前包括字典、列表
不可变序列:目前包括整数,字符串
区别在于可变序列可以进行增、删、查、改操作,而不可变序列不可以进行
字典的组成及原理
字典是由键值对组成的,字典是无序的排列方式,他不是根据你输入键的前后顺序来存储他,而是根据键的哈希值来存储
也是由于这个原因,字典的键必须是一个不可变序列,而且键不可以重复
语法格式如此:字典名={键:值,键:值,…}
字典的实现原理:
他是先由哈希函数计算键从而得到不同键的索引,然后根据键的索引排序键,键中保存的是值的地址,从而达到引用键而找到值的效果
字典特点:
1.字典中键值对是一一对应的,其中,键是不可以重复的,而值是可以重复的
2.字典中的键值对是无序的
3.字典是一种用空间换时间的数据结构
4.字典的键必须是不可变对象
字典的创建方式
1.通过{}创建字典
score={'tom':85,'jack':92,'sam':'pass'}
print(score) #输出{'tom': 85, 'jack': 92, 'sam': 'pass'}
print(type(score)) #输出<class 'dict'>
2.通过内置函数dict()创建字典
在()里面写入键值对,与{}不同的是,这种创建方式为键=值,而不是键:值,这点需要注意
student=dict(tom=85,jack=92,sam='pass')
print(student) #输出{'tom': 85, 'jack': 92, 'sam': 'pass'}
print(type(student))
3.创建一个空列表
empty={} #输出{}
print(empty)
empty1=dict()
print(empty1)
字典元素的获取
字典元素的获取有两种方法:
1.使用[]获取,[]里面是键值
print(score['tom']) #输出58
#print(score['alice']) #如果查找不到,就会报错:KeyError: 'alice'
2.使用get()方法获取
score={'tom':58,'linda':62,'jack':98}
print(score.get('tom')) #输出58
print(score.get('alice')) #如果查找不到就会输出:None,这个none是可以代替的,在键后面加入替代的值,找不到就会输出替代的值
print(score.get('alice',56)) #输出56,如果查找不到就会默认输出键后面的值
字典元素的增删改操作
字典元素的修改
dict={'tom':56,'jack':59,'marry':53,'刘桂香':77}
print(dict) #输出{'tom': 56, 'jack': 59, 'marry': 53, '刘桂香': 77}
dict['tom']=100
print(dict) #输出{'tom': 100, 'jack': 59, 'marry': 53, '刘桂香': 77}
字典元素的删除:
dict={'tom':56,'jack':59,'marry':53,'刘桂香':77}
print(dict) #输出{'tom': 56, 'jack': 59, 'marry': 53, '刘桂香': 77}
del dict['tom'] #删除会删除整个键值对
print(dict) #输出{'jack': 59, 'marry': 53, '刘桂香': 77}
字典元素的增加
dict={'tom':56,'jack':59,'marry':53,'刘桂香':77}
print(dict)
dict['alice']=5666
print(dict) #输出{'tom': 56, 'jack': 59, 'marry': 53, '刘桂香': 77, 'alice': 5666}
字典元素的清空
dict={'tom':56,'jack':59,'marry':53,'刘桂香':77}
print(dict) #输出{'tom': 56, 'jack': 59, 'marry': 53, '刘桂香': 77}
dict.clear()
print(dict) #输出{}
获取字典视图
实际上就是获取字典里面所有的键,所有的值,以及所有的键值对
这三种东西的获取方法各有不同,虽然方法各不一样,但是操作原理,用法都是一样的
获取所有的键
keys()函数
score={'tom':58,'linda':62,'jack':98}
a=score.keys()
print(a) #输出dict_keys(['tom', 'linda', 'jack'])
#可以将输出的键进行列表化,获得键的列表
print(list(a)) #输出['tom', 'linda', 'jack']
获取所有的值
values()函数
score={'tom':58,'linda':62,'jack':98}
b=score.values()
print(b) # 输出dict_values([58, 62, 98])
print(list(b)) #输出[58, 62, 98]
获取所有的键值对
items()函数
score={'tom':58,'linda':62,'jack':98}
print(score.items()) #输出dict_items([('tom', 58), ('linda', 62), ('jack', 98)])
print(list(score.items())) #输出[('tom', 58), ('linda', 62), ('jack', 98)]
字典元素的遍历
使用for in循环进行遍历
score={'tom':58,'linda':62,'jack':98}
for i in score: #这里的i表示的是键,如果要获取字典的值,就需要使用[]获取或者get函数获取
print(i,score[i],score.get(i))
字典生成式
d = {key: value for (key, value) in iterable}
其中iterable是一个可迭代的对象,比如list
元组
什么是元组
元组的创建方式
t = ('hello', 'world', 98)
t2='hello','xiaoming',76 #省略小括号
t3=('world',)
t4 = tuple(('nihao','lilei',89))
# 结果
('hello', 'world', 98) <class 'tuple'>
('hello', 'xiaoming', 76) <class 'tuple'>
('world',) <class 'tuple'>
('nihao', 'lilei', 89) <class 'tuple'>
元组的遍历
# 元素的遍历
t = ('hello', 'world', 98)
print(t[0])
print(t[1])
print(t[2])
# 或者
for item in t:
print(item)
#元组的新增
tup1=(11,22,33)
tup2=('hello','python')
tup=tup1+tup2
print(tup)
#结果
(11, 22, 33, 'hello', 'python')
#元组的删除
del tup1
print(tup1) #报错,删除了整个元组,无法打印
集合
什么是集合
集合的创建
集合的增删改查操作
新增
# 集合的创建
t1={10,20,30,40,50}
t1.add(60) #add一次添加一个元素
print(t1)
# t1.update({70,80,90})和t1.update((70,80,90))也可以新增元素
t1.update([70,80,90])
print(t1)
#结果
{40, 10, 50, 20, 60, 30}
{70, 40, 10, 80, 50, 20, 90, 60, 30}
移除
t1.remove(10)
print(t1)
# t1.remove(100) 移除没有的元素,出现报错,而使用discard没有报错
t1.discard(20)
t1.discard(100)
print(t1)
集合间的关系
s1={10,20,30,40,50,60,70}
s2={10,20,30,}
s3={10,20,80}
s4={100,200,300}
print(s1.issubset(s2)) #s1是s2的子集吗?结果为false
print(s1.issubset(s3))
print(s2.issubset(s1)) #s2是s1的子集吗?结果为true
print(s1.issuperset(s2)) #s1是s2的超集吗?结果为true
print(s2.isdisjoint(s3)) #s2与s3没有交集吗?结果为false
print(s2.isdisjoint(s4)) #s2与s4没有交集吗?结果为true
集合生成式
总结
字符串
字符串的驻留机制
字符串的常用操作
s='hello,hello'
print(s.index('lo')) #3
print(s.rindex('lo')) #9
print(s.find('lo')) #3
print(s.rfind('lo')) #9
大小写转换不能对元组和列表进行转换
s2='hello,world'
print(s2.center(20,'*'))
#结果:****hello,world*****
对元组和列表报错
s='hello world python'
lst=s.split()
print(lst) #从左边开始劈分,默认是空格字符串,返回是一个列表 ['hello', 'world', 'python']
s1='hello|world|python'
print(s1.split(sep='|')) #从左边开始劈分,以|作为劈分依据,返回个列表 ['hello', 'world', 'python']
print(s1.split(sep='|',maxsplit=1)) #从左边开始劈分,以|作为劈分依据,最大劈分次数为1,
# 劈分后剩下的子串作为单独的一部分,返回个列表 ['hello', 'world|python']
print(s1.rsplit(sep='|'))
print(s1.rsplit(sep='|',maxsplit=1)) #结果:['hello|world', 'python']
注释:水平制表符为空格,\t
print('2.','李四abc'.isalpha())
print('3.','张三'.isidentifier())
print('4',' '.isspace())
print('5.','123adb'.isalnum())
print(s2.replace('world','java')) #字符串替换replace,将world替换成java
s3='hello,python,python,python'
print(s3.replace('python','java',2)) #字符串替换replace,将Python替换成java,替换两次
s4=['hello','world','python'] #字符串组合,组合的元素必须是元组或列表
print('|'.join(s4)) #结果:hello|world|python
print(''.join(s4)) #结果:helloworldpython
print('*'.join('python')) #结果:p*y*t*h*o*n
字符串的比较
print('python'>'pytho') #true
print(ord('c')>ord('a')) #true
print(ord('c'),ord('a')) #99 97
print(chr(98)) #b
字符串的切片操作
# 字符串切片操作
s1='hello,python'
print(s1[1:5:1]) #从1开始截取到5(不包括5),步长为1
结果:ello
print(s1[::2]) #从0开始截取到最后,步长为2
结果:hlopto
print(s1[::-1]) #从0开始截取到最后,步长为-1
结果:nohtyp,olleh
print(s1[-6::1]) #索引从-6开始,到字符串最后一个元素结束,步长为1
结果:python
格式化字符串
name='张三'
age=14
money=14.3
new_str='我叫{0},今年{1}岁,身上有{2}元'.format(name,age,money)
print(new_str)
print('我叫%s,今年%i岁,身上有%.2f元' % (name,age,money))
# 结果
我叫张三,今年14岁,身上有14.3元
我叫张三,今年14岁,身上有14.30元
#表示字符串的宽度
print('%d' % 99) #字符串没有宽度
print('%10d' % 99) #10表示宽度
print('%.4f' % 3.1415296) #.4表示小数点后三位
print('%10.3f' % 3.1415296) #宽度+小数点后三位
#结果
99
99
3.1415
3.142
字符串的编码转换
s='斗破苍穹'
print(s.encode(encoding='GBK')) #在GBK编码格式中,一个中文占两个字节
print(s.encode(encoding='UTF-8')) #在GBK编码格式中,一个中文占三个字节
byte=s.encode(encoding='GBK') #编码
print(byte.decode(encoding='GBK')) #解码
byte=s.encode(encoding='UTF-8') #编码
print(byte.decode(encoding='UTF-8')) #解码
#结果
b'\xb6\xb7\xc6\xc6\xb2\xd4\xf1\xb7'
b'\xe6\x96\x97\xe7\xa0\xb4\xe8\x8b\x8d\xe7\xa9\xb9'
斗破苍穹
斗破苍穹
函数
函数的创建和调用
def cale(a,b):
c=a*b
return c
print(cale(5,4)) #结果为20
函数的参数传递
#函数的定义
def fun(arg1,arg2):
print('arg1=',arg1)
print('arg2=',arg2)
arg1=100 #重新赋值为100
arg2.append(10) #追加100
print('arg1=', arg1)
print('arg2=', arg2)
print('-------------------------------')
#函数的调用
n1=11
n2=[22,33,44]
print(n1,n2) #结果:11 [22, 33, 44]
fun(n1,n2) #将位置传参,agr1,arg2是函数定义的形参,n1,n2是函数调用的实参,总结:形参和实参名称可以不一致
print(n1,n2) #结果:11 [22, 33, 44, 10]
print('===============理解函数创建===========================')
def acl(s1,s2): #创建acl函数,s1,s2为形参
s1=50 #函数体,将s1修改为50,s2追加90
s2.append(90)
#对acl函数的调用
s1=5
s2=[10,20,30,40]
acl(s1,s2) #调用
print(s1,s2) #调用后的结果
'''在函数的调用过程中,进行参数的传递
如果是不可变对象,在函数体的修改不会影响到实参的值 arg1的值修改为100,不会影响n1的值
如果是可变对象,在函数体的修改会影响到实参的值 arg2的修改,append(10),会影响到n2的值
'''
#结果
11 [22, 33, 44]
arg1= 11
arg2= [22, 33, 44]
arg1= 100
arg2= [22, 33, 44, 10]
-------------------------------
11 [22, 33, 44, 10]
===============理解函数创建===========================
5 [10, 20, 30, 40, 90]
函数的返回值
def fun(num):
odd=[] #存奇数
even=[] #存偶数
for i in num: #遍历形参的元素
if i%2:
odd.append(i) #余数为1,结果为奇数,为true,存到odd中
else:
even.append(i) #余数为0,结果为偶数,为false,存到even中
return odd,even
lst=[10,20,33,44,47,57,60]
print(fun(lst))
#结果
([33, 47, 57], [10, 20, 44, 60])
结论
1、如果函数没有返回值,【函数执行完毕后,不需要给调用出提供数据】return可以省略不写
2、函数的返回值如果是1个,直接返回类型
3、函数的返回值如果是多个,返回结果是元组
函数的参数定义
def fun1(a=30, b=20):
print(a, b)
fun1(100)
fun1(50, 60)
#结果
100 20
50 60
def fun1(a,b,c):
print('a=',a)
print('b=',b)
print('c=',c)
fun1(10,20,30)
#将序列中的每个元素都转换为位置实参 使用*
lst1=[11,22,33]
fun1(*lst1)
fun1(a=100,b=200,c=300)
#将字典中的每个键值对都转换为关键字实参 使用**
dict={'a':111,'b':222,'c':333}
fun1(**dict)
#结果
a= 10
b= 20
c= 30
a= 11
b= 22
c= 33
a= 100
b= 200
c= 300
a= 111
b= 222
c= 333
def ext(a,b,*,c,d): #从*之后的参数,在函数调用时,只能采取关键字参数传递
print('a=', a)
print('b=', b)
print('c=', c)
print('d=', d)
# ext(10,20,30,40) #位置实参传递
# 要求,c,d只能采用关键字实参传递
ext(10,20,c=30,d=40) #前两个参数,采用的是位置实参传递,而c,d采用的是关键字实参传递
# 函数定义时的形参顺序问题
def ext1(a,b,*,c,d,**args):
pass
def ext2(*args,**args2):
pass
def ext3(a,b=10,*args,**args2):
pass
def ext(a,b,*,c,d): #从*之后的参数,在函数调用时,只能采取关键字参数传递
print('a=', a)
print('b=', b)
print('c=', c)
print('d=', d)
# ext(10,20,30,40) #位置实参传递
# 要求,c,d只能采用关键字实参传递
ext(10,20,c=30,d=40) #前两个参数,采用的是位置实参传递,而c,d采用的是关键字实参传递
# 函数定义时的形参顺序问题
def ext1(a,b,*,c,d,**args):
pass
def ext2(*args,**args2):
pass
def ext3(a,b=10,*args,**args2):
pass
变量的定义域
递归函数
def fun(n):
if n==1:
return 1
else:
return n*fun(n-1)
print(fun(6))
#结果:
720
斐波那契数列
#要求将前两位的数字相加等于第三位,第一和第二数字为1
def fib(n):
if n==1:
return 1
elif n==2:
return 1
else:
return fib(n-1)+fib(n-2)
print(fib(6))
#结果:8
异常
python异常处理机制
python中常见的异常类型
# print (10/0) #ZeroDivisionError
lst = [11, 22, 33, 44]
# print(lst[4])#IndexError索引从0开始
dic = {'name': '张三', 'age': 20}
# print(dic['gender']) #KeyError
# print (num) # NameError
# int a=20 #SyntaxError python中的变量没有数据类型
a = int('hello') # ValueError
traceback模块的使用
pycharm开发环境的调试
类与对象
定义python中的类
class Student: # Student为类的名称(类名)由一个或多个单词组成,每个单词的首字母大写,其余小写
native_pace = '吉林' # 直接写在类里的变量,称为类属性
def __init__(self, name, age): # 初始化方法
self.name = name # self.name称为实体属性,进行了一个赋值的操作,将局部变量的name的值赋给实体属性
self.age = age
# 实例方法
def eat(self):
print('学生在吃饭...')
# 静态方法
@staticmethod
def method(): # 静态方法中不能加self
print('我使用了staticmethod进行修饰,所以我是静态方法')
# 类方法
@classmethod
def cm(cls):
print('我是类方法,因为我使用了classmethod进行修饰')
# 类之外定义的叫函数,类里定义的叫方法
def drink():
print('喝水')
对象的创建
# 创建Student类的对象
stu1 = Student('张三', 20)
stu1.eat() # 对象名.方法名()
print(stu1.name)
print(stu1.age)
Student.eat(stu1) # 第二种调用方式, 类名.方法名(类的对象)-->实际上就是方法定义处的self
# 输出
'''学生在吃饭...
张三
20
学生在吃饭...'''
类属性、类方法、静态方法的使用方式
# 类属性的使用方式
print(Student.native_pace) # 访问类属性
stu1 = Student('张三', 20)
stu2 = Student('李四', 30)
print(stu1.native_pace)
print(stu2.native_pace)
'''输出:
吉林
吉林
吉林'''
#类方法的使用方式
Student.cm() # 实例方法需要传实例对象,而类方法通过类名来调用
'''输出: 我是类方法,因为我使用了classmethod进行修饰'''
#静态方法的使用方式
Student.method() # 没有默认参数,也是通过类名来调用
'''输出: 我使用了staticmethod进行修饰,所以我是静态方法'''
动态绑定属性和方法
class Student: # Student为类的名称(类名)由一个或多个单词组成,每个单词的首字母大写,其余小写
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self):
print(self.name + '在吃饭')
stu1 = Student('张三', 20)
stu2 = Student('李四', 30)
# 为stu1动态绑定性别属性
stu1.gender = '女'
print(stu1.name, stu1.age, stu1.gender)
'''输出: 张三 20 女'''
print(stu2.name, stu2.age)
'''输出: 李四 30'''
# 一个Student类可以创建N多个Student类的实例对象,每个实体对象的属性值不同
def show():
print('定义在类之外的,称函数')
# 为stu1动态绑定方法
stu1.show = show
stu1.show()
面向对象
面向对象的三大特性----封装、继承、多态
封装的实现方式
class Student:
def __init__(self, name, age):
self.name = name
self.__age = age # 年龄不希望在类的外部被使用,所以加了两个_
def show(self):
print(self.name, self.__age)
stu = Student('张三', 20)
stu.show()
# 在类外使用name
print(stu.name)
# print(stu.__age) 访问不了
print(stu._Student__age) # 在类的外部可以通过 _类名__属性名 进行访问,但是不建议
继承及其实现方式
class Person(object): # Person类继承object类
def __init__(self, name, age):
self.name = name
self.age = age
def info(self):
print(self.name, self.age)
class Student(Person): # Student类继承Person类
def __init__(self, name, age, stu_no):
super().__init__(name, age) # 使用super调用父类的方法
self.stu_no = stu_no
class Teacher(Person): # Teacher类继承Person类
def __init__(self, name, age, teachofyear):
super().__init__(name, age)
self.teachofyear = teachofyear
stu = Student('张三', 20, '1001')
teacher = Teacher('李四', 30, 10)
stu.info()
teacher.info()
'''输出:
张三 20
李四 30'''
#多继承
class A(object):
pass
class B(object):
pass
class C(A,B):
pass
class Person(object): # Person类继承object类
def __init__(self, name, age):
self.name = name
self.age = age
def info(self):
print(self.name, self.age)
class Student(Person): # Student类继承Person类
def __init__(self, name, age, stu_no):
super().__init__(name, age)
self.stu_no = stu_no
def info(self): # 重写父类的方法
super().info() # 先执行父类的方法
print(self.stu_no)
class Teacher(Person): # Teacher类继承Person类
def __init__(self, name, age, teachofyear):
super().__init__(name, age)
self.teachofyear = teachofyear
def info(self):
super().info() # 先执行父类的方法
print('教龄', self.teachofyear)
stu = Student('张三', 20, '1001')
teacher = Teacher('李四', 30, 10)
stu.info()
teacher.info()
'''输出:
张三 20
1001
李四 30
教龄 10'''
Object类
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return '我的名字是{0},今年{1}岁'.format(self.name, self.age)
stu = Student('张三', 20)
print(dir(stu))
print(stu) # 默认会调用__str__()这样的方法
'''输出:
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'name']
我的名字是张三,今年20岁'''
多态
python是动态语言,它只关心这个类有没有相应的方法,像上面的Person类没有继承Animal类,但它有eat()方法
这是与java等静态语言不一样的地方
特殊方法和特殊属性
特殊属性
class A(object):
pass
class B(object):
pass
class C(A, B):
def __init__(self, name, age):
self.name = name
self.age = age
# 创建C类的对象
x = C('jack', 20) # x是C类的一个实例对象
print(x.__dict__) # 实例对象的属性字典
print(C.__dict__) # 类的属性字典
print('--------')
print(x.__class__) # 输出对象所属的类
print(C.__bases__) # 输出C类的父类类型的元素
print(C.__mro__) # 类的层次结构
print(A.__subclasses__()) # 子类的列表
'''输出:
{'name': 'jack', 'age': 20}
{'__module__': '__main__', '__init__': <function C.__init__ at 0x000001D9042EBDC0>, '__doc__': None}
--------
<class '__main__.C'>
(<class '__main__.A'>, <class '__main__.B'>)
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
[<class '__main__.C'>]
'''
特殊方法
class Student:
def __init__(self, name):
self.name = name
def __add__(self, other):
return self.name + other.name
def __len__(self):
return len(self.name)
stu1 = Student('张三')
stu2 = Student('李四')
s = stu1 + stu2 # 实现了两个对象的加法运算(因为在Student类中编写_add__()特殊的方法)
print(s)
print(len(s))
class Person(object):
def __new__(cls, *args, **kwargs):
print('__new__被调用执行了,cls的id值为{0}'.format(id(cls)))
obj = super().__new__(cls)
print('创建对象的id值为{0}'.format(id(obj)))
return obj
def __init__(self, name, age):
print('__init__被调用了,self的id值为{0}'.format(id(self)))
self.name = name
self.age = age
print('object这个类对象的id为{0}'.format(id(object)))
print('Person这个类对象的id为{0}'.format(id(Person)))
# 创建Person类的实例对象
p1 = Person('张三', 20)
print('p1这个Person类的实例对象的id:{0}'.format(id(p1)))
'''输出:
object这个类对象的id为140707984993104
Person这个类对象的id为1427494206928
__new__被调用执行了,cls的id值为1427494206928
创建对象的id值为1427495955328
__init__被调用了,self的id值为1427495955328
p1这个Person类的实例对象的id:1427495955328
'''
类的浅拷贝与深拷贝
class CPU:
pass
class Disk:
pass
class Computer:
def __init__(self, cpu, disk):
self.cpu = cpu
self.disk = disk
# (1)变量的赋值
cpu1 = CPU()
cpu2 = cpu1
print(cpu1, id(cpu1))
print(cpu2, id(cpu2))
# (2)类的浅拷贝
print('------------')
disk = Disk() # 创建一个Disk类对象
computer = Computer(cpu1, disk) # 创建一个Computer类对象
# 浅拷贝
import copy
print(disk)
computer2 = copy.copy(computer)
print(computer, computer.cpu, computer.disk)
print(computer2, computer2.cpu, computer2.disk)
#深拷贝
print('------------')
computer3=copy.deepcopy(computer)
print(computer, computer.cpu, computer.disk)
print(computer3, computer3.cpu, computer3.disk)
'''输出:
<__main__.CPU object at 0x0000020638BF65E0> 2225745126880
<__main__.CPU object at 0x0000020638BF65E0> 2225745126880
------------
<__main__.Disk object at 0x0000020638BC86D0>
<__main__.Computer object at 0x0000020638C0D430> <__main__.CPU object at 0x0000020638BF65E0> <__main__.Disk object at 0x0000020638BC86D0>
<__main__.Computer object at 0x0000020638C0DC70> <__main__.CPU object at 0x0000020638BF65E0> <__main__.Disk object at 0x0000020638BC86D0>
------------
<__main__.Computer object at 0x000001F78328D430> <__main__.CPU object at 0x000001F7832765E0> <__main__.Disk object at 0x000001F7832486D0>
<__main__.Computer object at 0x000001F784ED7310> <__main__.CPU object at 0x000001F784ED7370> <__main__.Disk object at 0x000001F784ED76A0>
'''
模块
什么叫模块、模块化编程的好处
模块的导入
导入自定义的模块需要 右键当前目录,选择Mark Directory as,再选择Sources Root
以主程序方式运行
if __name__=='__main__': # 只有运行当前程序时,才会执行pass代码
pass
python中的包
使用import方式进行导入时,只能跟包名或模块名
使用from …import可以导入包,模块,函数,变量
python中常用的内置模块
第三方模块的安装与使用
文件操作
编码格式
文件读写原理
常用的文件打开模式
文件对象的常用方法
With语句
with open(' logo.png','rb') as src_file:
with open('copy2logo.png','wb') as target_file:
target_file.write(src_file.read ())
以上代码实现文件的复制
文件操作推荐使用with语句,这样不用手动去写关闭操作
目录操作
#OS 模块是与操作系统相关的一个模块
import os
os.system('notepad.exe') #打开记事本
os.system('calc.exe') #打开计算器
# 接调用可执行文件
os.startfile('C:\\Program Files\\Tencent\\QQ\\Bin\\qq.exe')
实操案例——学生信息管理系统
import os
filename = 'student.txt'
def main():
while True:
menu()
choice = int(input('请选择'))
if choice in range(0, 8):
if choice == 0:
answer = input('您确定要退出系统吗? y/n')
if answer == 'y' or answer == 'Y':
print('感谢您使用本系统!!')
break # 退出系统
else:
continue
elif choice == 1:
insert() # 录入学生信息
elif choice == 2:
search() # 查找学生信息
elif choice == 3:
delete() # 删除学生信息
elif choice == 4:
modify() # 修改学生信息
elif choice == 5:
sort() # 排序
elif choice == 6:
total() # 统计学生总人数
elif choice == 7:
show() # 显示所有学生信息
def menu():
print("====================学生信息管理系统====================\n")
print('--------------------功能菜单---------------------------')
print('\t\t\t\t\t1.录入学生信息')
print('\t\t\t\t\t2.查找学生信息')
print('\t\t\t\t\t3.删除学生信息')
print('\t\t\t\t\t4.修改学生信息')
print('\t\t\t\t\t5.排序')
print('\t\t\t\t\t6.统计学生总人数')
print('\t\t\t\t\t7.显示所有学生信息')
print('\t\t\t\t\t0.退出')
print('-----------------------------------------------------')
def insert(): # 录入学生信息
student_list = []
while True:
id = input('请输入ID(如1001):')
if not id:
break
name = input('请输入姓名:')
if not name:
break
try:
english = int(input('请输入英语成绩:'))
python = int(input('请输入Python成绩:'))
java = int(input('请输入java成绩:'))
except:
print('输入无效,不是整数类型,请重新输入')
continue
# 将录入的学生信息保存到字典中
student = {'id': id, 'name': name, 'english': english, 'python': python, 'java': java}
# 将学生信息添加到列表中
student_list.append(student)
answer = input('是否继续添加? y/n')
if answer == 'y':
print()
continue
else:
print()
break
# 调用save()函数
save(student_list)
print('学生信息录入完毕!!')
def save(lst): # 将学生信息录入文件中
try:
stu_txt = open(filename, 'a', encoding='utf-8')
except:
stu_txt = open(filename, 'w', encoding='utf-8')
for item in lst:
stu_txt.write(str(item) + '\n')
stu_txt.close()
def search(): # 查找学生信息
student_query = []
while True:
id = ''
name = ''
if os.path.exists(filename):
mode = input('按ID查找请输入1,按姓名查找请输入2:')
if mode == '1':
id = input('请输入学生ID:')
elif mode == '2':
name = input('请输入学生姓名:')
else:
print('您的输入有误,请重新输入!')
search()
with open(filename, 'r', encoding='utf-8') as rfile:
student = rfile.readlines()
for item in student:
d = dict(eval(item))
if id != '': # 按ID查
if d['id'] == id:
student_query.append(d)
elif name != '': # 按姓名查
if d['name'] == name:
student_query.append(d)
# 显示查询结果
show_student(student_query)
# 清空列表
student_query.clear()
answer = input('是否继续查询? y/n')
if answer == 'y' or answer == 'Y':
continue
else:
break
else:
print('暂未保存学生信息')
return
def show_student(lst):
if len(lst) == 0:
print('没有查找到学生信息,无数据显示!!!')
return
# 定义标题显示格式
format_title = "{:^6}\t{:^12}\t{:^8}\t{:^10}\t{:^10}\t{:^8}"
print(format_title.format('ID', '姓名', '英语成绩', 'Python成绩', 'Java成绩', '总成绩'))
# 定义内容显示格式
format_data = "{:^6}\t{:^12}\t{:^8}\t{:^8}\t{:^8}\t{:^8}"
for item in lst:
print(format_data.format(item.get('id'),
item.get('name'),
item.get('english'),
item.get('python'),
item.get('java'),
int(item.get('english')) + int(item.get('python')) + int(item.get('java'))
))
def delete(): # 删除学生信息
while True:
student_id = input('请输入要删除的学生的ID:')
if student_id != '':
if os.path.exists(filename): # 文件存在
with open(filename, 'r', encoding='utf_8')as file:
student_old = file.readlines()
else: # 文件不存在
student_old = []
flag = False # 标记是否删除
if student_old:
with open(filename, 'w', encoding='utf_8') as wfile:
d = {}
for item in student_old:
d = dict(eval(item)) # 将字符串转成字典
if d['id'] != student_id:
wfile.write(str(d) + '\n') # 将不需要删除的学生信息再次写入
else:
flag = True
if flag:
print(f'id为{student_id}的学生信息已被删除')
else:
print(f'没有找到ID为{student_id}的学生信息')
else:
print('无学生信息')
break
show() # 删除之后重新显示所有学生信息
answer = input('是否继续删除? y/n')
if answer == 'y' or answer == 'Y':
continue
else:
break
def modify(): # 修改学生信息
show()
if os.path.exists(filename): # 文件存在
with open(filename, 'r', encoding='utf-8')as rfile:
student_old = rfile.readlines() # 原来的学生信息放入列表中
else:
return
student_id = input('请输入要修改的学生的ID:')
with open(filename, 'w', encoding='utf-8') as wfile:
for item in student_old:
d = dict(eval(item))
if d['id'] == student_id:
print('找到学生信息,可以进行修改了!')
while True:
try:
d['name'] = input('请输入姓名:')
d['english'] = input('请输入英语成绩:')
d['python'] = input('请输入Python成绩:')
d['java'] = input('请输入java成绩:')
except:
print('您的输入有误,请重新输入!!!')
else:
break
wfile.write(str(d) + '\n') # 将修改后的信息写入文件
print('修改成功!!!')
else:
wfile.write(str(d) + '\n') # 将未修改的信息也写入原文件
answer = input('是否继续修改其他学生信息? y/n')
if answer == 'y' or answer == 'Y':
modify()
def sort(): # 排序
show()
if os.path.exists(filename):
with open(filename, 'r', encoding='utf-8') as rfile:
student_list = rfile.readlines()
student_new = []
for item in student_list:
d = dict(eval(item))
student_new.append(d)
else:
return
asc_or_desc = input('请选择:(0.升序 1.降序)')
if asc_or_desc == '0':
asc_or_desc_bool = False
elif asc_or_desc == '1':
asc_or_desc_bool = True
else:
print('您的输入有误,请重新输入')
sort()
mode = input('请选择排序方式(1.按英语成绩排序 2.按Python成绩排序 3.按Java成绩排序 0.按总成绩排序):')
if mode == '1':
student_new.sort(key=lambda x: int(x['english']), reverse=asc_or_desc_bool)
elif mode == '2':
student_new.sort(key=lambda x: int(x['python']), reverse=asc_or_desc_bool)
elif mode == '3':
student_new.sort(key=lambda x: int(x['java']), reverse=asc_or_desc_bool)
elif mode == '0':
student_new.sort(key=lambda x: int(x['english']) + int(x['python']) + int(x['java']), reverse=asc_or_desc_bool)
else:
print('您的输入有误,请重新输入!!!')
sort()
show_student(student_new)
def total(): # 统计学生总人数
if os.path.exists(filename):
with open(filename, 'r', encoding='utf-8') as rfile:
students = rfile.readlines()
if students:
print(f'一共有{len(students)}名学生')
else:
print('暂未保存学生的信息!')
def show(): # 显示所有学生信息
student_list = []
if os.path.exists(filename):
with open(filename, 'r', encoding='utf-8') as rfile:
students = rfile.readlines()
for item in students:
student_list.append(eval(item))
if student_list:
show_student(student_list)
else:
print('暂未保存数据信息!!!')
if __name__ == '__main__':
main()