python(学习笔记-自用)

本文介绍了Python编程的基本概念,包括变量、数据类型、字符串编码、控制结构、函数、字典和列表等。讲解了如何使用Python进行算术运算、字符串操作、循环结构、函数定义和调用,以及字典和列表的创建、遍历和修改。此外,还探讨了异常处理、面向对象编程、文件操作和模块导入。通过实例,深入理解Python编程的核心概念和技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1.print()

2.转义字符

3.二进制与字符编码

4.标识符和保留字

5.变量的定义和使用

6.变量的多次赋值

7.数据类型

8.整数类型

9.浮点类型

10.布尔类型

11.字符串类型

12.数据类型转换

13.注释

14.input函数的使用

15.运算符——算术运算符

16.赋值运算符

17. 比较运算符

 18.布尔运算符

 19.位运算符

20.运算符的优先级

21.顺序结构

22.对象的布尔值

23.分支结构

24.条件表达式

25.pass语句

26.range函数

 27.循环结构

28.else语句

29.嵌套循环

30.二重循环中的break和continue

31.列表 

32.列表的创建

33.切片操作——获取列表中的多个元素

34.列表元素的增加操作

35.列表元素的删除操作: 

36.列表元素的修改

37.列表元素的排序操作

38.列表生成式

39.字典

40.字典的创建

41.字典的增删改

42.字典的视图操作

43.字典元素的遍历

44.字典的常用操作

45.字典的特点

46.字典生成式

47.元组

48.为什么要将元组设计成不可变序列

49.元组的遍历

50.集合

51.集合的相关操作

52.集合之间的关系

53.集合的数学操作 

54.集合生成式

总结:

 55.字符串的创建和驻留机制

56.字符的常用操作

57.格式化字符串 

58.字符串的编码转换

59.函数的创建和调用

60.函数的参数传递

61.函数的返回值 

62.函数的参数定义

63.函数的参数定义

 函数的参数总结

64.变量的作用域

65.递归函数

66.bug

67.try...except...else结构

68.常见的异常类型

 69.traceback模块

70.面向对象

71.类的创建

 72.对象的创建(类的实例化)

73.类属性,类方法,静态方法

74.动态绑定属性和方法

75.面向对象的三大特征

76.特殊方法和特殊属性 

77.类的浅拷贝与深拷贝

78.模块

79.自定义模块和模块的导入

80.以主程序形式运行

81.python中的包

82.常用的内置模块

83.编码格式

 84.文件的读写原理

85.常用的文件打开模式

86.文件对象的常用方法

87. 目录操作:

88.os.path模块操作目录相关函数





1.print()

可以输出数字print(520)

可以输出字符串print('hello word')

含有运算符的表达式print(3+1)#会计算表达式的结果

将数据输出到文件中

fp=open('D:/text.txt','a+')#a+以读写的方式打开文件,a+如果文件不存在就创建,存在就打开继续追加
print('Hello world',file=fp)#要使用file=fp
fp.close()#关闭

不进行换行输出(输出内容在一行当中)

print("hello","world","HFF")

2.转义字符

转义字符就是:反斜杠+想要实现的转义功能首字母

换行\n                   回车\r                 水平制表符\t                    退格\b

print("hello \nworld")
print("hello \tworld")#四个字符一个表格 0_ _ _
print("helloooo \tworld")#_ _ _ _ 看\t之前是否占满制表位,占满就重新开一个,没占满接着用

print("hello\rworld") #回车,world把hello覆盖掉了
print('hello\bworld')#退一个格,把o退掉了

\\第一个斜线是反斜线,第二个相当于转义字符但又不是

print("http:\\www.baidu.com")

http:\www.baidu.com#少了一个斜线

print(http:\\\\www.baidu.com)

http:\\www.baidu.com#两个\\会转出一个\

print(”老师说:\"大家好\"")

\"表示这不是”不再是字符串的边界而是 字符串中应该输出的内容

原字符,不希望字符串中的转义字符起作用,就是在字符串之前加上r或R

print(r"hello\nworld")#最后一个字符不能是反斜杠
print(r"hello\nworld\\")#两个可以

3.二进制与字符编码

8个位置(bit)为一个字节,1024个字节等于1KB(千),1024KB=1MB(兆),1024MB=1GB(吉)1024GB=1TB(太)

print(chr(0b100111001011000))#乘 0b-二进制
print(ord(乘))#0rd十进制

4.标识符和保留字

严格区分大小写

import keyword
print(keyword.kwlist)#查看保留字

5.变量的定义和使用

变量由三部分组成:

标识:表示对象所存储的内存地址,使用内置函数id(obj)来获取

类型:表示的是对象的数据类型,使用内置函数type(obj)来获取

值:表示对象所存储的具体数据,使用print(obj)可以将值进行打印输出

name='懒羊羊'
print(name)
print('标识',id(name))
print('类型',type(name))
print('值',name)

6.变量的多次赋值

多次赋值以后,变量名会指向新的空间,原来name id指向的空间变成了内存垃圾

name='懒羊羊'
name='灰太狼'
print(name)

7.数据类型

整数类型——>int——>100

浮点数类型——>float——>3.14156

布尔类型——>bool——>True,False

字符串类型——>str——>'朝闻道,夕死可矣'

8.整数类型

十进制——默认进制,取值0-9

二进制——以0b开头,取值0-1

八进制——以0o开头,取值0-7

十六进制——以0x开头,取值0-9和A-F

print('二进制',0b10101111)

9.浮点类型

浮点数存储不精确性

使用浮点数进行计算时,可能会出现小数位数不确定的情况

n1=1.1
n2=2.2
print(n1+n2)

解决方案:导入模块decimal

from decimal import Decimal
print(Decimal('1.1')+Decimal('2.2'))

10.布尔类型

布尔值可以转化为整数

True——1

False——0

f1=False
print(f1+1)#直接转

11.字符串类型

字符串又称不可变的字符序列

可以使用单引号,双引号,三引号来定义

单引号和双引号定义的字符串必须在一行

三引号定义的字符串可以分布在连续的多行

str1='朝闻道,夕死可矣'
str2="朝闻道,夕死可矣"
str3="""朝闻道,
        夕死可矣"""

12.数据类型转换

将不同数据类型的数据拼接在一起

str()     int()        float()

name='懒羊羊'
age=8
print('我叫'+name+'今年'+str(age)+'岁')

int()      1.文字类和小数类字符串,无法转化成整数   2.浮点数转成整数,抹0取整

float()   1.文字类无法转成浮点型,2.整数转为浮点型,末尾会加.0   3.小数类字符串可以转


13.注释

单行注释:以#开头,直到换行结束

多行注释:并没有单独的多行注释标记,将一对三引号之间的代码称为多行注释,不赋值给任何变量

中文编码声明注释:在文件开头加上中文声明,用于指定源码文件的编码格式

print('hello')

"""
我是懒羊羊,
我爱吃青草蛋糕
"""

python默认的存储编码是utf-8

#coding:gbk

"""
我是懒羊羊,
我爱吃青草蛋糕
"""

用记事本打开,另存为可以看到改为了


14.input函数的使用

作用:接收来自用户的输入·,结果是一个str类型

present=input('懒羊羊想要什么礼物呢?')
print(present)
#从键盘中输入两个整数,计算两个整数的和
a=input('请输入一个加数:')
a=int(a)
b=input('请输入另一个加数:')
b=int(b)
print(a+b)


print('-'*30)

a=int(input('请输入一个加数:'))

b=int(input('请输入另一个加数:'))

print(a+b)

15.运算符——算术运算符

标准算术运算符——加(+),减(-),乘(*),除(/),整除(//)

取余运算符——%

幂运算符——**

print(9//-4)#结果为-3,一正一负整除,向下取整

print(-9%4) # 3  -9-4*(-3)
print(9%-4) #-3   9-(-4)*(-3)

"""
看书
"""

16.赋值运算符

=   执行顺序:从右到左

     支持链式赋值——a=b=c=20    #将20赋给 a,b,c,a=20,b=20.c=20

    支持参数赋值——+=,-=,*=,/=,//=,%=

a=20
a+=30 #相当于a=a+30
print(a) #50

a-=10 #相当于a=a-10
print(a) #40


a*=2 #相当于a=a*2

a/=3 #相当于a=a/2


a//=2 #相当于a=a//2

   支持系列解包赋值——a,b,c=20,30,40   a=20,b=30,c=40#等号左右个数相同都是3个

#交换两个变量的值
a,b=10,20
a,b=b,a

17. 比较运算符

对变量或表达式的结果进行大小,真假等比较;比较运算符的结果为bool类型

>  ,< , >= , <=,  !=

==   “一个等号称为赋值运算符,两个等号称为比较运算符”

        一个变量由三部分组成:标识,类型,值

        == 比较的是值

        比较对象的标识使用  is

a=10
b=10
print(a==b)   #True 说明a与b的值相等
print(a is b)  #True   说明a与b的ID标识相等

lst1 = [11,22,33,44]
lst2 = [11,22,33,44]
print(lst1==lst2)   #true
print(lst1 is lst2) #false

     is not  ID是不相等的


 18.布尔运算符

对于布尔值之间的运算

and         or         not         in        not in

and 两个都是真,结果才为真

or 只要有一个为真,结果就为真

not 取反

f=True
print(not f)

in 在不在当中

s='hello world'
print('w' in s)
print('K' not in s)

 19.位运算符

将数据先转成二进制再进行计算

位与&——>对应位数都是1,结果数位才是1,否则为0

位或|——>对应位数都是0,结果数位才是0,否则为1

 左移位运算符<<    高位溢出舍弃,低位补0

右移位运算符<<    低位溢出舍弃,高位补0

print(4<<1) #向左移动一个位置,相当于乘以2
print(4<<2) #向左移动两个位置

print(4>>1) #向右移动一个位置,相当于除以2

print(4>>2) #向右移动两个位置,相当于除以4


20.运算符的优先级

** 

*,/,//,%                   算术运算符:先算乘除再算加减,有幂最先

+,-


>> ,<<

&                                  位运算

I


> ,< ,>=,<=,==,!=      比较运算符 :结果true或者false


and

or                              布尔运算  


=                               赋值运算



21.顺序结构

程序的组织结构:顺序结构,选择结构,循环结构

顺序结构:程序从上到下顺序的执行代码,中间没有任何的判断和跳转,直到程序的结束


22.对象的布尔值

python一切皆对象,所有的对象都有一个布尔值

  获取对象的布尔值:        使用内置函数bool()

 以下对象的布尔值为false

false        数值0        none        空字符串        空列表        空元组        空字典        空集合

#测试对象的布尔值
print(bool(False)) 
print(bool(0.0))
print(bool(None))  

print(bool([]))   #空列表【】
print(bool(list()))    #空列表list()

print(bool(()))   #空元组()
print(bool(tuple()))   #空元组tuple()


print(bool({}))  #空字典{}
print(bool(dict()))   #空字典dict()


print(bool(set()))   #空集合  

 其他对象的布尔值均为True

age=int(input("请输入你的年龄"))


if age:
    print(age)
else:
    print("年龄为:",age)

23.分支结构

单分支结构

if 条件表达式:

        条件执行体

money=1000 #余额
s=int(input('请输入取款金额')) #取款金额
#判断余额是否充足
if money>=s:
    money=money-s
    print('取款成功,余额为:',money)

双分支结构

if 条件表达式:

        条件执行体1

else:

        条件执行体2

#双分支结构
"""
从键盘录入一个整数,编写程序让计算机去判断是奇数还是偶数
"""
n=int(input("请输入一个整数"))

if n%2==0
    print(n,'这是一个偶数')
else:
    print(n,"这是一个奇数")

多分支结构

if     条件表达式1:

       条件执行体1

elif 条件表达式2:

      条件执行体2

elif 条件表达式N:

     条件执行体N

[else:]

   条件执行体N+1

"""多分支结构,多选一执行

从键盘录入一个整数成绩
90-100 A
80-89  B
70-79  C
60-69  D
0-59   E
大于100或小于0  非法
0
"""
score=int(input("请输入一个成绩:"))
#判断
 if 90<=score<=100        #python中可以这样写
    print('A级')
elif score >=80 and score<=89
    print("B级")
elif score >=70 and score<=79
    print("C级")
elif score >=60 and score<=69
    print("D级")
else 
    print("非法")

嵌套IF

语法结构:

if 条件表达式1:    

        if 内层条件表达式:

                内存条件执行体1

        else

                内存条件执行体2

else:

        条件执行体

answer=input("您是会员吗?y/n")
money=float(input("请输入你的购物金额:"))
if answer=='y' :   #会员
    print("会员")
    if money>=200:
        print("打八折,付款金额为:",money*0.8)
    elif money>=100:
        print("打九折,付款金额为:",money*0.9)
    else:
        print("不打折,付款金额为:",money)
else:              #非会员
    print("非会员")
    if money>=200:
        print("打九五折,付款金额为:",money*0.95)
    else
         print("不打折,付款金额为:",money)
        
        

24.条件表达式

条件表达式是if.....else的简写

语法结构.

x if 判断条件 else y       t条件执行正确,往前运行错误往后运行

运算规则

如果判断条件的布尔值是True,条件表达式的返回值为x,否则条件表达式的返回值为False

"""
从键盘录入两个整数,比较两个整数的大小
"""
num_a=int(input('请输入第一个整数'))
num_b=int(input('请输入第二个整数'))

#比较大小
if num_a>=num_b:
    print(num_a,"大于等于",num_b)
else:
    print(num_a,'小于',num_b)


print('+'*30)

#使用条件表达式
print(   print(num_a,"大于等于",num_b)  if num_a>=num_b  else   (num_a,'小于',num_b)  )



print( print(str(num_a)+"大于等于"+str(num_b)  if num_a>=num_b  else ....)


25.pass语句

语句什么都不做,只是一个占位符,用在语法上需要语句的地方

什么时候用:先搭建语法结构,还没想好代码怎么写的时候

if语句的条件执行体

for——in语句的循环体

定义函数时的函数体

answer=input("您是会员吗?y/n")
money=float(input("请输入你的购物金额:"))
if answer=='y' :   #会员
    pass
 
else:              #非会员
   pass
 

26.range函数

range(stop):创建一个[ 0,stop)之间的整数序列,步长为1

range(start,stop):创建一个[ start,stop)之间的整数序列,步长为1

range(start,stop,step):创建一个[ start,stop)之间的整数序列,步长为step

返回值是一个迭代器对象

r=range(10)
print(r)  #range(0,10)查看不了

print(list(r)) #用于查看range对象中的整数序列

range的优点:不管range对象表示的整数序列有多长,所有的range对象占用的内存空间都是相同的,因为仅仅需要存储star,stop和step,只有当用到range对象时,才会去计算序列中的相关元素

in 和not in 判断整数序列中是否存在(不存在)指定的整数

r=range(1,10,2)
print(10 in r)

 27.循环结构


while 条件表达式:

        循环体(条件执行体)

当条件表达式的值为False的时候,退出循环

while是判断N+1次,条件为True执行N次

if是判断一次,条件为True执行一次

四布循环法:初始化变量         条件判断         条件执行体(循环体)         改变量

#计算1:10之间的累加和
"""初始化变量"""
a=0
sum=0
"""条件判断"""
while a<11
"""条件执行体"""
    sum+=a
"""改变变量"""
    a+=1
    print("和为:",sum)

 for-in循环

for  自定义的变量 in 可迭代对象:

        循环体

in ——表示从(字符串,序列等)中依次取值,又称遍历

for-in遍历的对象必须是可迭代对象

for item in "Python":   # p y t h o n
    print(item)

 range()产生一个整数序列,也可以是一个迭代对象

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

如果在循环体中不需要使用带自定义变量,可以将自定义变量写为''_''

for i in range(5):
    print('救命啊,喜羊羊')  #救命啊,喜羊羊将运行五次
"""
输出100到999之间的水仙花数
举例:
153=3*3*3+5*5*5+1*1*1
***

for item in range(100,1000)
    ge=item%10
    shi=item//10%10   #多看看
    bai=item//100
    #print(ge,shi,bai)
    if ge**3+shi**3+bai**3==item
        print(item)

流程控制语句——break

用于结束循环结构,通常与分支结构if 一起使用

""" 从键盘录入密码,最多录入三次,如果正确就结束循环 """

for item in range(3):
    pwd=input("请输入密码")
    if pwd='8888'
        print('密码正确')
        break
    else:
        print('密码不正确')



a=0
while a<3:
    pwd=input("请输入密码:")
    if pwd='8888'
        print('密码正确')
        break
     else:
        print('密码不正确')
    """改变变量"""
    a+=1
    

continue

用于结束当前循环,进入下一次循环,通常与分支if一起使用

""" 要求输出1到50之间的所有5的倍数"""


for item in range(1,51)
    if item%5==0
        print(item)




for item in range(1,51)
    if item%5!=0
        continue
    print(item)

28.else语句

else可以和if,while ,for搭配

for/while.....                                  

        ....                                   

else:                                  

        ...

没有碰到break时执行else

for item in range(3):
    pwd=input("请输入密码:")
    if pwd=='8888'
        print("密码正确")
        break
    else:
        print("密码不正确")

else:
    print ("对不起,三次密码均输入错误")

29.嵌套循环

在循环结构中又嵌套了另外的完整的循环结构,其中内层循环作为外层循环的循环体执行,

外层循环一次,内层循环一轮

"""输出一个三行四列的矩阵 """
for i in range(1,4) :  #行数
    for j in range(1,5):
        print('*',end='\t') #不换行输出
    print() #打行
#9*9乘法表,第一行一个,第二行两个

for i in range(1,10):
    for j in range(1,i+1):
        print(i'*'j,'=',i*j,end='\t')
    print()

30.二重循环中的break和continue

二重循环中的break和continue用于控制本层循环


""" 流程控制语句break与continue在二重循环中的使用"""
for i in range(5):    #代表外层循环要执行五次
    for j in range(1,11):
        if j%2==0:
            break
        print(j,end="\t")



#结果
1
1
1
1
1


31.列表 

变量可以存储一个元素,而列表是一个“大容器”可以存储N多个元素,程序可以方便地对这些数据进行整体操作

变量存储的是一个对象的引用(id)

list=['hello','world',98]

32.列表的创建

列表需要使用中括号【】,元素之间使用英文的逗号进行分隔

        lst = ['l懒羊羊','喜欢','睡觉']

使用内置函数list()

        lst2=list(['helo','world',98])

    列表对象——赋给lst2 =id 987

    ide:987       type:list       value:'helo','world',98

列表的特点:

列表元素按顺序有序排列

索引映射唯一的数据

列表可以存储重复数据

任意数据类型混存

根据需要动态分配和回收内存——不用担心列表不够用

 print(lst2[0],lst2[-3])

列表的查询操作

如果列表中存在N个相同元素,只返回相同元素中的第一个元素的索引

如果查询的元素在列表中不存在,则会抛出ValueError

还可以在指定的start和stop之间进行查找

lst=['hello','world',98,'hello']
print(lst.index('hello'))
#print(lst.index('python'))
 print(lst.index('hello'.1,3))  #在'world',98,没有hello会报错
print(lst.index('hello',1,4))  #3

33.切片操作——获取列表中的多个元素

列表名[start:stop:step]

切片的结果:原列表片段的拷贝

切片的范围:[start,stop)

step默认为1   start默认是0    stop默认是最后一个元素(包含最后一个)

lst = [10,20,30,40,50,60,70,80]
print(lst[0:7])
print(lst[0::1])



"""
[10, 20, 30, 40, 50, 60, 70]
[10, 20, 30, 40, 50, 60, 70, 80]
"""
lst = [10,20,30,40,50,60,70,80]
print(lst[1:6:1])  #[20 30 40 50 60] 
print(lst[1:])   #[20 30 40 50 60 70 80] 

切出来的是一个新的列表对象,ID不一样

step为负数,逆序

lst = [10,20,30,40,50,60,70,80]
print(lst[::-1])  #[80,70,60,50,40,30,20,10] 
print(lst[7::-1])  #[80,70,60,50,40,30,20,10] 
print(lst[6:0:-2])  #[70,50,30] 

判断指定元素在列表中是否存在

lst=[10,20,'python','hello']

print(10 in lst)

print(10 not in lst)

 列表元素的遍历

lst = [10,20,30,40,50,60,70,80]
for item in lst:
    print(item)

34.列表元素的增加操作


增加操作:

append()    :在列表的末尾添加一个元素

extend()     :在列表的末尾至少添加一个元素

insert()      :在列表的任意位置添加一个元素

切片          :在列表的任意位置添加至少一个元素

lst = [10 ,20 ,30]

lst.append(100)   #[ 10, 20, 30, 40],增加后的列表和原列表标识(ID)相同



lst2=['heelo','world']
lst.extend(lst2)   #[10 ,20 ,30,'heelo','world']


lst=[10 ,20 ,30,'heelo','world']
lst.insert(1,90)    #[10,90,20 ,30,'heelo','world']


lst=[10,90,20 ,30,'heelo','world']     
lst3=[True,False,'hello']   #[10,True,False,'hello']   切掉的部分用一个新的列表替换
lst[1:]=lst3    #从90开始切

35.列表元素的删除操作: 

remove()  :一次删除一个元素    重复元素只删除第一个     元素不存在抛出ValueError

pop()    :删除一个指定索引位置上的元素     指定索引不存在抛出ValueError,不指定索引,删除列表中最后一个元素

切片:一次至少删除一个元素

clear():清空列表

del 删除列表

lst = [10,20,30,40,50,60,30]

lst.remove(30)
print(lst)

lst.remove(3000)
print(lst)



lst = [10,20,30,40,50,60,30]
lst.pop(1)
lst.pop(10000)
lst.pop()


#切片,切片将会产生一个新的列表对象
lst=[10,40,50,60]
new_list=lst[1:3]   #切片后的列表[40,50]


"""切片:不产生新的列表对象,而是删除原列表的内容"""
lst[1:3]=[]
print(new_list)


lst.clear()
print(lst)    #[]   清除列表中的所有元素

'''del语句将列表对象删除'''
del lst
print(lst)    #没有定义




36.列表元素的修改

为指定索引的元素赋予一个新值

为指定的切片赋予一个新值

lst=[10,20,30,40]
lst[2]=100  #[10,20,100,40]



lst[1:3]=[300,400,500,600] #[10,300,400,500,600,40]

37.列表元素的排序操作

sort()    :默认从小到大的顺序进行排序,也可以指定reverse=True,进行降序排序,排序是在原列表上进行的

sorted() :可以指定reverse=True,进行降序排序,原列表没有产生变化,而是产生了一个新的列表

lst=[20,40,50,10,98,5]
print("排序前的列表",lst,id(lst))

#开始排序
lst.sort()       #等同  lst.sort(reverse==False)
print('排序后的列表',lst,id(lst))    #id没变,排序是在原列表上进行的


#指定关键字参数,进行降序排序

lst.sort(reverse==True)
print('排序后的列表',lst,id(lst))    #id没变,排序是在原列表上进行的



#使用内置函数sorted()对列表进行排序,将产生一个新的列表

lst=[20,40,50,10,98,5]
new_list=sorted(lst)
print(lst)          #原列表没有产生变化,而是产生了一个新的列表
print(new_list)



#降序排列
desc_list=sorted(lst,reverse=True)

38.列表生成式

列表生成式简称:“生成列表的公式”

语法格式:

[ i *i  for i in range(1,10)]

i*i:列表元素的表达式,列表中真正包含元素的值

lst=[i for i in range (1,10) ]

lst=[i*i for i in range (1,10) ]

lst=[i*2 for i in range (1,6) ]

39.字典

字典与列表一样是一个可变序列【可以增删改】

以键值对的方式存储数据,字典是一个无序的序列     键:值

列表【】   字典{  }

第一个放入字典中的,不一定在字典中处于第一个位置,所以说它无序

hash(key)——>,把键放到hash(哈希函数)中进行计算得到的位置,放到字典中的键必须是不可变序列,不可变序列作为键的时候不管怎么动哈希值计算出来都是相同的。

整数序列和字符串序列都是不可变序列

字典的实现原理:与查字典类似,查字典是先根据部首或拼音查找相应的页码,python中的字典是根据key查找value所在位置

hash(key)——>value所在的位置

40.字典的创建

最常用的方式:使用花括号

scores={'懒羊羊':0 , '喜羊羊':100}

使用内置函数dict()

dict(name='jack',age=20)

dict(name='懒羊羊',age=8)     #等号左侧是键,等号右侧是值

空字典d={}

41.字典的增删改

key的判断  in:指定的key在字典中存在返回True

               not in:指定的key在字典中不存在存在返回True

"""
键的判断
"""
scores={"懒羊羊":0,'喜羊羊':100}

print("懒羊羊" in scores)

字典元素的删除

"""
字典元素的删除
"""
del scores=['喜羊羊']

scores['美羊羊']=80    #新增元素

scores['美羊羊']=90    #修改元素

scores.clear()   #清空字典的元素

42.字典的视图操作

keys():获取字典中所有key

values():获取字典中所有Value

items():获取字典所有key,value对

keys=scores.keys()  #字典键类型
print(list(keys))#将所有的key组成的视图转化为列表


values=scores.values() #字典值类型
print(list(values))


items=scores.items() 

print(list(items))#列表中的每一个元素都是一个元组(‘懒羊羊’,100)

43.字典元素的遍历

for item in scores :

        print(item)      #item是字典中的键

        print(scores[item],scores.get(item))  #获取字典的值,第一个会抛异常,而另一个不会

44.字典的常用操作

字典中元素的获取

[]:举例scores['张三']

get()方法:举例scores.get("张三")

【】如果字典中不存在指定的key,抛出keyError异常

get()方法取值,如果字典中不存在指定的key,不会抛出异常而是返回None,可以通过参数设置默认的value,以便指定的key不存在时返回

scores={'懒羊羊':0,"喜羊羊":100}
scores['懒羊羊']  #0
scores.get('懒羊羊')

scores.get('美羊羊',99) #查找'美羊羊'所对的value不存在时,提共一个默认值99

45.字典的特点

字典中的所有元素都是一个键值对,key不允许重复,value可以重复

字典中的元素是无序的

字典中的key必须是不可变对象

字典也可以根据需要动态地伸缩

字典会浪费较大的内存,是一种使用空间换时间的数据结构

d={'懒羊羊':'100','懒羊羊':0}   #结果后面的0干掉了前面的100,懒羊羊0分,【key不允许出现重复】

d={'懒羊羊':'100','喜羊羊':100}   #{'懒羊羊':'100','喜羊羊':100}  value可以重复

46.字典生成式

内置函数zip()

items=['Fruits','books','others']
prices=[96,78,85]


d={item:price for item,price in zip(items,prices)}

d={item.upper:price for item,price in zip(items,prices)}  #变大写


items=['Fruits','books','others']
prices=[96,78,85,100,200]   #以元素少的生成


47.元组

元组是不可变序列

不可变序列:字符串,元组

不可变序列——没有增删改的操作

可变序列:列表,字典

可变序列:可以对序列执行增删改操作,对象地址不发生更改

元组的创建方式:

t=('python','hello',90)   #这种方式小括号可以不写    t='python','hello',90

t=tuple('Python','hello',90)

只包含一个元组的元素需要使用逗号和小括号t=(10,)    t=('懒羊羊',)#如果不加逗号会认为是本身的数据类型。

空元组的创建方式:t=()   t5=tuple()

48.为什么要将元组设计成不可变序列

在多任务环境下,同时操作对象时不需要枷锁

因此,在程序中尽量使用不可变序列

  可以看里面的数据,可以从里面拿数据,但是你不能对里面的数据进行修改,谁看都一样,不会对里面的内容进行破坏

注意事项:元组中存储的是对象的引用

(a):如果元组中对象本身是不可变对象,则不能再引用其他对象

(b):如果元组中的对象是可变对象,则可变对象的引用不允许改变,但数据可以改变。

t=(10,[20,30],9)
print(t)
print(type(t))  #元组

print(t[0],type(t[0]),id(t[0]))  #整数

print(t[1],type(t[1]),id(t([1])))  #列表

print(id(100))
t[1]=100  #报错   元组不允许,修改元素


#但是 【20,30】是列表,列表是可变序列,所以可以向列表中添加元素,而列表的内存地址不变

t[1].append(100)
print(t)   #不允许修改元组中元素的引用,但是你可以修改元素中可变对象的添加内容

49.元组的遍历

元组是可迭代对象,所以可以使用for...in进行遍历

t=tuple(('python','hello',90))

for item in t:

        print(item)


50.集合

与列表,字典一样都属于可变类型的序列

集合是没有value的字典

直接{}

s={'python','hello',90}

s={2,3,44,44}  #集合中的元素不允许重复,重复的会被去掉

使用内置函数set()

s1=set(range(6))


set(列表)

set((1,2,4,5,65)) #{65,1,2,4,5} 集合中的元素是无序的

set(字符串)
s=set('懒羊羊')

print(s,type(s))  #{'羊', '懒'} <class 'set'>   

定义一个空集合

s={}  ——>字典类型

set():这样才是一个空集合

51.集合的相关操作

集合元素的判断操作:in 或 not in 

集合元素的新增操作:add(),一次添加一个元素

                                  update()至少添加一个元素

s={10,20,40,60}
print(10 is s)

s.add('懒羊羊')

s.update({200,'灰太狼',0}) #放集合
s.update([200,100,0])  #放列表
s.update((200,100,0))  #放元组

集合元素的删除操作:

一次删除一个指定元素

remove(),一次删除一个指定元素,如果指定的元素不存在抛出KeyError

discard(),一次删除一个指定元素,如果指定的元素不存在,不会抛出异常

s={10,20,40,60}
s.remove(10)
s.discard(500)

一次只删除一个任意元素:pop(),不能添加参数

s={10,20,40,60} #随机删除一个元素,不能指定
s.pop()

clear():清空集合

s.clear() :清空

52.集合之间的关系

两个集合是否相等:可以使用运算符==或!=进行判断(元素相同,就相等)

只要是内容相同,底部的存储顺序就是相同的{'懒羊羊','喜羊羊'}=={'喜羊羊','懒羊羊'}

一个集合是否是另一个集合的子集:issubset    

s1={10,20,30,40,50,60}

s2={10,20}

print(s2.issubset(s1))

#True

一个集合是否是另一个集合的超集: issuperset

s1={10,20,30,40,50,60}

s2={10,20}

print(s1.issuperset(s2))

#True

两个集合是否没有交集:isdisjoint

s1={10,20,30,40,50,60}

s2={10,20,100,5000}

print(s1.isdisjoint(s2))

#False——有交集为FALSE

53.集合的数学操作 

交集   ,并集,差集,对称差集

 原集合不会发生变化

s1={10,20,30,40}
s2={20,30,40,50,60}

#交集intersection()与&等价

print(s1.intersection(s2))
print(s1 & s2)
print(s1)#不变
print(s2)#不变

#并集union()与|等价
print(s1.union(s2))
print(s1|s2)


#差集操作  dofference()与-等价
print(s1.dofference(s2))  #10
print(s1-s2)

#对称差集
print(s1.symmetric_difference(s2))
print(s1^s2)   #{50,10,60}

54.集合生成式

元组没有生成式

用于生成集合的公式:{i*i for i in range(1,10)}#将{}改为【】就是列表生成式

总结:

 55.字符串的创建和驻留机制

字符串是一个不可变的字符序列

字符串的定义

a='python'
b="python"
c=""" python """   这三个字符串的内存地址都是相同的

字符串的驻留机制:仅保存一份相同且不可变字符串的方法,不同的值被存放在字符串的驻留池中,python的驻留机制对相同的字符串只保留一份拷贝,后续创建相同的字符串时,不会开辟新空间,而是把该字符串的地址赋给新创建的变量

驻留机制的集中情况:字符长度为0或1时

                                  符合标识符的字符串(字母数字下划线)

                                 字符串只在编译时进行驻留,而非运行时

                                【-5,256】之间的整数数字

强制驻留:sys中的intern方法强制2个字符串指向同一个对象

pycharm对字符串进行了优化处理

pycharm
s1='abc%'
s2='abc%'
print(s1 is s2)


#ture

驻留机制的优缺点

当需要值相同的字符串时,可以直接从字符串池里拿来使用,避免频繁的创建和销毁,提升效率和节约内存,因此拼接字符串和修改字符串是会比较影响性能的

在需要进行字符串拼接时建议采用str类型中的join方法,而非+,因为join()方法是先计算出所有字符串中的长度,然后再拷贝,只new一次对象,效率比+效率高 

56.字符的常用操作

字符的查询

index():查找子串substr第一次出现的位置,如果查找的子串不存在时,则抛出Valueerror

rindex() : 查找子串substr最后一次出现的位置,如果查找的子串不存在时,则抛出Valueerror

find():查找子串substr第一次出现的位置,如果查找的子串不存在时,则返回-1

rfind():查找子串substr最后一次出现的位置,如果查找的子串不存在时,则返回-1

s='喜羊羊,懒羊羊'
print(s.index('羊羊'))  #1
print(s.find('羊羊'))   #6
-7-6-5-4-3-2-1
0123456

 字符串大小写转换

upper():全部转化成大写

lower() : 全部转成小写

swapcase() :大小写颠倒

capitalize():把第一个字符转成大写,其余字符转成小写

title():把每个单词的第一个字符转成大写,把每个单词的剩余字符转换为小写

s='hello,python'
a=s.upper()
print(a,id(a))
print(s,id(s))  #字符串是不可变序列,你改变后会产生一个新的字符串对象

b=s.lower()
print(b,id(b))  #转换之后,会产生一个新的字符串对象,值没变
print(b is s)   #false

c='hello,Python'
print(c.swapcase()) #大小写互换

字符串内容对齐

center():居中对齐,第一个参数指定宽度,第二个参数指定填充符,第二个参数是可选的,默认是空格,如果设计宽度小于实际宽度则返回原字符串

s='hello,python'
print(s.center(20,'*'))

ljust() 左对齐,第一个参数指定宽度,第二个参数指定填充符,第二个参数是可选的,默认是空格,如果设计宽度小于实际宽度则返回原字符串     右边打*

rjust()右对齐,.......,左边打***,字母右对齐

zfill()右对齐,左边用0填充,该方法只接受一个参数,用于指定 字符串的宽度,如果设计宽度小于实际宽度则返回原字符串 

print('-8910'.zfill(8))  #-0008910

字符串的分割

split():从左边开始分割,默认的分割字符是空袼字符串,返回值是一个列表

          通过参数sep指定分割字符串的分隔符

         通过参数maxsplit指定分割字符串时的最大分割次数,在经过最大分割之后,剩余的子串会单独做为一部分

s1='hello|world|python'
print(s1.split(sep='|'))  #['hello', 'world', 'python']
print(s1.split(sep='|',maxsplit=1))  #['hello', 'world|python']

     rsplit()从字符串的右侧分割

判断字符串操作的方法


isidentifier():判断指定的字符串是不是合法的标识符

s='hello,python'
print(s.isidentifier()) #FAlse,合法的标识符(字母,数字,下划线)

isspace():判断指定的字符串是否全部由空白字符组成(回车,换行,水平制表符)

isalpha():判断指定字符串是否全部由字母组成  ( ‘懒羊羊’也是全部由字母组成)

isdecimal():判断指定字符串是否全部由十进制的数字组成(罗马数字VII不是)(’123四‘不是)

isnumeric():判断指定的字符串是否全部由数字组成(’123四‘是)(罗马数字VII是)

isalnum():判断指定字符串是否全部都由字母和数字组成


字符串的替换replace()    第一个参数指定被替换的子串,第二个参数指定替换子串的字符串,,第三个参数指定最大的替换次数,替换前的字符串不发生变化

s='hello python'
print(s.replace('python','C语言'))  #hello c语言
print(s)  #hello python


s1='hello python python'
print(s.replace('python','C语言',2))   #hello c语言 c语言

字符串的合并 join(),将列表或元组中的字符串合并成一个字符串

lst=['hello','java','python']    lst=('hello','java','python')  
print('|'.join(lst))

print(''.join(lst))


#hello|java|python
hellojavapython

print('*'.join('python')) #它把python作为字符串序列进行一个连接

# p*y*t*h*o*n


字符串的比较操作:

>,<, >=,<=,==,!=

比较规则:首先比较两个字符串中的第一个字符,如果相等则继续比较下一个字符,依次比较下去,直到两个字符串中的字符不相等时,其比较结果就是两个字符串的比较结果,两个字符串中的所有后续字符将不再被比较

比较原理:两个字符进行比较时,比较的是其ordinal value(原始值),调用内置函数ord可以指定字符的ordinal value。与内置函数ord对应的内置函数chr,调用内置函数chr时指定ordinal value可以得到其对应的字符

print('apple'>'app')
print(ord('a'),ord('b'))   #97 98
print(chr(97))    #a

print(ord('懒'))  #25042
print(chr(25042)) #懒

"""==与is的区别"""

==比较的value

is 比较的是id是否相等

字符串的切片操作 

字符串是不可变类型:不具备增删改等操作,切片操作将产生新的对象

切片[start:end:step]

s='hello,python'
s1=s[:5]  #hello,没指定其实位置,从0开始
s2=s[6:]  #python   由于没有指定结束位置,所以切到字符串的最后一个元素
s3="!"
str=s1+s3+s2  #hello!python
s[-6::1]  #python


s1 s2 s3 str四个ID都不同
s='hello,python'
s1=s[-1:-5:-1]
print(s1)


#noht

57.格式化字符串 

按一定格式输出的字符串

格式化字符串的两种方式  

%: %s——字符串   %i或者%d——整数  %f——浮点数

name='懒羊羊'
age=8
print('我叫%s,今年%d' % (name,age))
                     |
                     |
                     固定符号

{}

'我的名字叫;{0},今年{1},我真的叫:{0}'.format(name,age)   
#标0使用format中的第一个位置的数,标1使用format中的第二个位置的数

f-string

name='懒羊羊'
age=8
print(f'我叫{name},今年{age}岁')

表示精度和宽度

print('%10d' % 99) #10-表示的是宽度
print('%f' % 3.1415926) #3.141593
print('%.3f' % 3.1415926) #保留三位小数


print('%10.3f' % 3.1415926) %宽度是10,保留三位小数

58.字符串的编码转换

编码与解码的方法

编码:将字符串转换为二进制数据(bytes)

解码:将bytes类型的数据转换成字符串类型

s='朝闻道'
#编码
print(s.encode(encoding='GBK'))   #GBK编码格式中一个中文占两个字节
#b'\xb3\xaf\xce\xc5\xb5\xc0'    b——表示二进制的意思

print(s.encode(encoding='utf-8'))  #utf-8,一个中文占三个字节

#解码
byte=s.encode(encoding='GBK') #编码
print(byte.decode(encoding='GBK')) #encoding='GBK'解码的类型   byte代表的就是一个二进制数据(字节类型数据)

'''编码格式和解码格式要相同'''

59.函数的创建和调用

为什么要需要函数:重复使用代码,隐藏实现细节,提高可维护性,提高可读性便于调试

函数的创建:   def    函数名([输入函数])

                                函数体

                                [renturn xxx]

#函数的创建
def calc(a,b):
    c=a+b
    return c

函数的调用

result=calc(10,20)
print(result)

60.函数的参数传递

上面的代码 a,b占了两个实际变量的位置——形参,形参的位置是在函数的定义处

calc(10,20) #10,20称为实际参数值,称为实参,实参的位置是函数的调用处

位置实参:根据形参对应的位置进行实参传递,一个萝卜一个坑

关键字实参:根据形参名称进行实参传递

calc(b=10,a=20) #  =左侧的变量的名称称为关键字参数

def calc(a,b):

 内存分析:形参和实参的参数名称可以不相同

在函数调用过程中,进行参数的传递:如果是不可变对象,在函数体的修改不会影响实参的值;

如果是可变对象,在函数体的修改会影响实参的值

def fun(arg1, arg2):
    print('arg1', arg1)
    print('arg2', arg2)
    arg1 = 100
    arg2.append(10)
    print('arg1', arg1)
    print('arg2', arg2)


n1 = 11
n2 = [22, 33, 44]
print('n1', n1)
print('n2', n2)
fun(n1, n2)
print('n1', n1)
print('n2', n2)

n1 11
n2 [22, 33, 44]
arg1 11
arg2 [22, 33, 44]
arg1 100
arg2 [22, 33, 44, 10]
n1 11
n2 [22, 33, 44, 10]

进程已结束,退出代码 0
 

61.函数的返回值 

函数返回多个值时,结果为元组

def fun(num):
    odd=[]#存奇数
    even=[]#存偶数
    for i in num:
        if i%2:
            odd.append(i)
        else:
            even.append(i)
    return odd,even


print(fun([10,29,34,23,44,56,59]))

([29, 23, 59], [10, 34, 44, 56]) 

1.如果函数没有返回值,【函数执行完毕之后,不需要给调用处提供数据】,return可以省略不写

2.函数的返回值,如果是一个,直接返回原类型:你是列表我就是列表,你是实数我就是实数

3.函数的返回值,如果是多个,返回的结果为元组                                                                 

def fun1()
    print('青草蛋糕')

fun1
def fun2():
    return 'hello'

res=fun2()
print(res)
def fun3()
    return 'hello','world'
print(fun3())

函数在定义时,是否需要返回值,视情况而定


62.函数的参数定义

函数定义时,给形参设置默认值,只有与默认值不符的时候才需要传递实参

def fun(a,b=10)
    print(a,b)

#函数的调用
fun(100)    #(100,10)
fun(20,30)  #(20,30)

63.函数的参数定义

个数可变的位置参数

定义函数时,可能无法事先确定传递的位置实参的个数时,使用可变的位置参数

使用*定义个数可变的位置形参

结果为一个元组

def fun(*args):   
    print(arges)


fun(10)
fun(10,20,30)

(10,)  
(10,20,30)



def fun2(*a,*b)
    pass
#程序会报错,个数可变的位置参数,只能是1个

个数可变的关键字形参

定义函数时,无法事先确定传递的关键字实参的个数时,使用可变的关键字形参

使用**定义个数可变的关键字形参

结果为一个字典

def fun(**args):
    print(args)


fun(a=10)
fun(a=10,n=20,c=30)

{'a': 10}
{'a': 10, 'n': 20, 'c': 30}



def fun2(**a,**b)
    pass
#程序会报错,个数可变的关键字参数,只能是1个

 在一个函数的定义过程中,既有个数可变的关键字形参,也有位置可变的位置形参,要求,个数可变的位置形参,放在个数可变的关键字形参之前

 函数的参数总结

def fun(a,b,c):
    print('a=',a)
    print('b=',b)
    print('c=',c)

fun(10,20,30)#函数调用时的参数传递,称为位置传参  a=10,b=20,c=30
lst=[11,22,33]
fun(lst)  #程序报错,你有三个参数,你只传了一个
fun(*lst) #在函数调用时,将列表中的每个元素都转换为位置实参传入

fun(a=100,c=300,b=200)#函数的调用,所以是关键字实参

dict={"a":111,"b":222,"c":333}
fun(**dic)  #在函数的调用时,将字典中的键值对都转换为关键字实参传入

def fun(a,b=10) :  #b是在函数的定义处,所以b是形参,而且进行了赋值,所以b称为默认值形参
    print('a=',a)
    print('b=',b)
     
def fun2(*arges):  #个数可变的位置形参
    print(arges)

     
def fun2(**arges):  #个数可变的关键字形参
    print(arges)

def fun4(a,b,c,d):
    print('a=',a)
    print('b=',b)
    print('c=',c)
    print('d=',d)
fun4(10,20,30,40)#位置实参传递
fun4(a=10,b=20,c=30,d=40)#关键字实参传递
fun4(10,20,c=30,d=40)#混用

"""c,d只能采用关键字实参传递"""
def fun4(a,b,*,c,d): #从*之后的参数,在函数调用时,只能采用关键字参数传递
    print('a=',a)
    print('b=',b)
    print('c=',c)
    print('d=',d)

''' 函数定义时的形参的 顺序问题'''
def fun5(a,b,*,c,d,**args)

    pass

def fun5(*args1,**args2)

    pass

def fun5(a,b=10,*args1,**args2)

    pass


64.变量的作用域

局部变量:在函数内定义并使用的变量,只在函数内部有效,局部变量使用global声明,这个变量实际上就变成了全局变量

全局变量:函数体外定义的变量,可作用于函数内外

def fun(a,b)
    c=a+b    #c,就称为局部变量
    print(c)


print(c)#报错,c超出了起作用的范围


name="懒羊羊" #name为全局变量
print(name)


def fun2():
    print(name)
#调用函数
fun2()

def fun3():
    global age#局部变量使用global声明,这个变量实际上就变成了全局变量
    age=20
    print(age)

fun3()
print(age)

65.递归函数

 如果一个函数的函数体内调用了该函数本身,这个函数就称为递归函数

递归的组成部分:递归调用与递归终止条件

递归的调用过程:每递归调用一次函数,都会在栈内存分配一个栈帧

                          每执行完一次函数,都会释放相应的空间

递归的优缺点: 缺点——占用内存多,效率低下

                        优点——思路和代码简单

def fac(n):
    if n==1:
        return 1
    else:
        return n*fac(n-1)

print(fac(7))   #7的阶乘
def fid(n):
    if n==1:
        return 1
    elif n==2:
        return1
    else:
        renturn fib(n-1)+fid(n-2)


#斐波那契数列

print(fid(6))

#输出这个数列的前六位上的数字
for i in range(1,7)
    print(fib(i))

66.bug

debug:排除bug

思路不清:使用print()函数,或#暂时注释部分代码

异常处理机制:

多个except结构捕获异常,先子类后父类的顺序

try:
    a=int(input('请输入第一个整数'))
    b=int(input('请输入第二个整数'))
    result=(a/b)
    print('结果为:'result)
except ZeroDivisionError:   #不允许被0除的异常,子
    print('除数不允许为0')
except ValueError:
    print('只能输入数字串')
print('程序结束')

67.try...except...else结构

如果try块没有抛出异常,则执行else块,如果try中抛出异常,则执行except块

try:
    a=int(input('请输入第一个整数'))
    b=int(input('请输入第二个整数'))
    result=(a/b)
    print('结果为:'result)
except BaseException as e:
    print('出错了')
    print(e)
else:
    print('结果为:',result)

 try...except...else...finally:finally块无论是否发生异常都会被执行,常用来释放try块中申请的资源

try:
    a=int(input('请输入第一个整数'))
    b=int(input('请输入第二个整数'))
    result=(a/b)
except BaseException as e:
    print('出错了')
    print(e)
else:
    print('结果为:',result)
finally:
    print('无论是否产生异常,总会被执行的代码')
print('程序结束')

68.常见的异常类型

ZeroDivisionError——除0异常

IndexError——序列中没有此索引

KeyError——映射中没有这个键

NameError——未声明对象

SyntaxError——python语法错误

int a=20  

ValueError——传入无效的参数

a=int('hello')

 69.traceback模块

使用traceback模块打印异常信息

#print(10/0)

import traceback

try:
    print('_____________________')
    print(1/10)
except:
    traceback.print_exc()

 调试模块:小虫子,红色当前执行,蓝色下一步要执行

70.面向对象

面向过程面向对象
区别事物比较简单,可以用线性的思维去解决事物比较复杂,使用简单的线性思维无法解决
共同点面向过程和面向对象都是解决实际问题的一种思维方式
二者相辅相成,并不是对立的
解决复杂问题,通过面向对象方式便于我们从宏观上把握事物之间的复杂的关系,
方便我们分析整个系统;具体到微观操作,仍然使用面向过程方式来处理   。

71.类的创建

创建类的语法

class Student: #Student为类的名称(类名)由一个或多个单词组成,每个单词的首字母大写,其           pass                  余小写

对象 :ID 类型 值 

print(id(Student))

print(type(Student))

print(Student)

有值,类对象

类的组成:类属性,实例方法,静态方法,类方法

class Student:
    native_pace='陕西'  #直接写在类面的变量,称为类属性

    def_init_(self,name,age):
        self.name=name   #self.name称为实例属性,进行了一个赋值的操作
        self.age=age 
        


    #实例方法                 #在类之外定义的称为函数,在类之内定义的称为方法    
    def eat(self):
        print('青草蛋糕')

    #类方法
    @classmethod
    def cm(cls):
        print("类方法")


    #静态方法
    @staticmethod
    def sm():   ——这里面不允许写self
        print('静态方法')

 72.对象的创建(类的实例化)

语法: 实例名=类名()

#创建Student类的对象
stu1=Student('张三',20)
stu1.eat()   == Student.eat(stu1) #对象名.方法名  =  类名.方法名(类的对象)
print(stu1.name)
print(stu1.age)



print(id(stu1))
print(stu1)
print(type(stu1))

print('-'*30)

print(id(Student))
print(Student)
print(type(Student))

73.类属性,类方法,静态方法

类属性:类中方法外的变量称为类属性,被该类的所有对象所共享

print(Student.native_pace)
stu1=Student('懒羊羊',0)
print(Stu1native_pace)
Student.native_pace='大肥羊学校'
print(Stu1native_pace)
print(Student.native_pace)

类方法:使用@classmethod修饰的方法,使用类名直接访问的方法

Student.cm()

静态方法:使用@staticmethod修饰的方法,使用类名直接访问的方法

Student.sm()

74.动态绑定属性和方法

python是动态语言,在创建对象之后,可以动态地绑定属性和方法

class Student:
    def _init_(self,name,age)
        self.name=name
        self.age=age
    def eat(self):
        print(self.name+'在吃饭')

stu1=Studeng('懒羊羊',8)

stu2=Studeng('喜羊羊',9)

一个Student类可以创建N多个Student类的实例对象,每个实例对象的属性值不同(name,age)

只想给stu1添加一个青草蛋糕,不给stu2添加

print('-----为stu1动态绑定性别属性-----')
stu1.food='青草蛋糕'

print(stu1.name,stu1.age,stu1.food)

print(stu2.name,stu2.age)
print('---------------')
stu1.eat()
stu2.eat()

def show():
    print('定义在类之外的,称为函数')

stu1.show=show
stu1.show()

stu2.show()#会报错,这个没有绑定show方法,stu1.show=show这里叫方法

类属性,类方法,静态方法都是类名打点使用的  对象名.方法名 )

实例方法  对象名.方法名  =  类名.方法名(类的对象)   这里有self,self就是Student的类对象 


75.面向对象的三大特征

封装:提高程序的安全性

​​​​​​ 将数据(属性)和行为(方法)包装到类对象中。在方法内部对属性进行操作,在类对象的外部调用方法。这样,无需关心方法内部的具体实现细节,从而隔离复杂度

在python中没有专门的修饰符可用于属性的私有,如果该属性不希望在类对象外部被访问,前面使用两个"_"

class Student:
    def __init__(self,name,age):
        self.name=name
        self.__age=age
    def show(self):
        print(self.name,self.__age)
stu=Student('懒羊羊',8)
stu.show()

#在类的外面使用name与age
#print(stu.__age)
#查看stu的所有属性和方法
print(dir(stu))
print(stu.Student__age)  #8被获取到了

继承:提高代码的复用性

class 子类类名(父类1,父类2...);  

        pass

 如果一个类没有继承任何类,则默认继承object

python支持多继承——父类可以写多个

定义子类时,必须在其构造函数中调用父类的构造函数

class Person(object):
        def __init__(self,name,age):
            self.name=name
            self.age=age
        def  info(self):
            print(self.name,self.age)

class Student(Person):
    def __init__(self,name,age,stu_id):
        super().__init__(name,age)
        self.stu_id=stu_id

class Teacher(Person):
    def __init__(self,name,age,teachofvear):
        super().__init__(name,age)
        self.teachofvear=teachofvear

stu=Student('懒羊羊',8,1010103)
teacher=Teacher('慢羊羊',50,30)
stu.info()
teacher.info()
懒羊羊 8
慢羊羊 50
class A(object):
    pass
class B(object):
    pass
class C(A,B):
    pass

object()有两个子类A,B,C类继承了A和B,C有两个父类A和B

 方法重写:

如果子类对继承自父类的某个属性或方法不满意,可以在子类中对其(方法体)进行重新编写 

子类重写后的方法中可以通过suoer().XXX()调用父类中被重写的方法

class Person(object):
        def __init__(self,name,age):
            self.name=name
            self.age=age
        def  info(self):
            print(self.name,self.age)

class Student(Person):
    def __init__(self,name,age,stu_id):
        super().__init__(name,age)
        self.stu_id=stu_id
    def info(self):
        super().info()  #调用父类的方法
        print(stu_id)

class Teacher(Person):
    def __init__(self,name,age,teachofvear):
        super().__init__(name,age)
        self.teachofvear=teachofvear

stu=Student('懒羊羊',8,1010103)
teacher=Teacher('慢羊羊',50,30)
stu.info()
teacher.info()

object类 :object类是所有类的父类,因此所有类都有object类的属性和方法

内置函数dir()可以查看指定对象所有属性

Object有一个__str__()方法,用于返回一个对于‘对象的描述’,对应于内置函数str()经常用于print()方法,帮助我们查看对象的信息,所以我们经常会对__str__()进行重写

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('懒羊羊',8)
print(dir(stu))  #不会输出对象的内存和地址了,而是调用__str__函数
print(stu) #默认调用__str__()这样的方法
print(type(stu))


['__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']
我的名字是懒羊羊,今年8岁了
<class '__main__.Student'>

多态:提高程序的可扩展性和可维护性 

 多态就是‘具有多种形态’,它指的是:几遍不知道一个变量所引用的对象到底是什么类型,仍然可以通过这个变量调用方法,在运行过程中根据变量所引用对象的类型,动态决定调用哪个对象中的方法

class Animal(object):
    def eat(self):
        print('动物会吃')
class Dog(Animal):
    def eat(self):
        print('狗吃骨头')
class Cat(Animal):
    def eat(self):
        print('猫吃鱼')
class Person():
    def eat(self):
        print('人吃五谷')

#定义一个函数
def fun(obj):
    obj.eat()
#开始调用函数
fun(Cat())
fun(Dog())
fun(Animal())
print('++++++')
fun(Person())


猫吃鱼
狗吃骨头
动物会吃

静态语言实现多态的三个必要条件:继承,方法重写,父类引用指向子类对象----Java

动态语言的多态崇尚‘鸭子类型’当看到一直鸟走起来像鸭子,游起来像鸭子,那么这只鸟就可以被称为鸭子。在鸭子类型中,不需要关心对象是什么类型,到底是不是鸭子,只关心对象的行为——python 

76.特殊方法和特殊属性 

特殊属性 __dict__  获取类对象或实例对象所绑定的所有属性和方法的字典

#print(dir(object))
class A:
    pass
class B:
    pass
class C(A,B):
    def __init__(self,name):
        self.name=name

#创建C类的对象
x=C('WXH') #X是C类型的一个实例对象
print(x.__dict__)

#

{'name': 'WXH'}  name属性#实例对象的属性字典
print(C.__dict__)#类对象,可以看到属性和方法

#{'__module__': '__main__', '__init__': <function C.__init__ at 0x0000024A0BF5A840>, '__doc__': None}

print(x.__class__)  #对象所属的类

print(C.__bases__)  #C类的父类的元组,(<class '__main__.A'>, <class '__main__.B'>)
print(C.__base__)  #根C离得最近的父类出来
print(C.__mro__)#查看类的层次结构 
#(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
print(A.__subclasses__()) #获取A的子类的列表

特殊方法

__len__() 通过重写__len__()方法,让内置函数len()的参数可以是自定义类型

__add__()通过重写__add__()方法,可使自定义对象具有“+”功能

__new__()用于创建对象

__init__()对创建的对象进行初始化

a=20
b=100
c=a+b #两个整数类型的对象的相加操作
d=a.__add__(b)
print(c,d)

class Student:
    def __init__(self,name)
        self.name=name
    
    def __add__(self,other):
        return self.name+other.name    1

    def __len__(self):
        return len(self.name)

stu1=Student('懒羊羊')
stu2=Student('喜羊羊')
s=stu1+stu2  #没有1def会报错

s=stu1.__add(stu2)

print('---------')
lst=[1,2,5,8]
print(len(lst))  #4
print(lst.__len__())  #4


print(len(stu1))


 __new__和__init__

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('懒羊羊',8)
print('p1这个Person类的实例对象的id:{0}'.format(id(p1)))

77.类的浅拷贝与深拷贝

变量的赋值操作:只是形成两个变量,实际上还是指向同一个对象

浅拷贝:python拷贝一般都是浅拷贝,拷贝时,对象包含的子对象内容不拷贝,因此,源对象与拷贝对象会引用同一个子对象

深拷贝:使用copy模块的deepcopy函数,递归拷贝对象中包含的子对象,源对象和拷贝对象所有的子对象也不相同。

class CPU:
    pass
class Disk:
    pass
class Computer:
    def__init__(self,cpu,disk)
        self.cpu=cpu
        self.disk=disk

#变量的赋值
cpu1=CPU()
cpu2=cpu1
print(cpu1)
print(cpu2)

#类的浅拷贝
disk=Disk() #创建一个硬盘类的对象
computer=Computer(cpu1,disk) #创建一个计算机类的对象

#浅拷贝
import copy
computer2=copy.copy(computer)
print(computer,computer.cpu,computer.disk)
print(computer2,computer2.cpu,computer2.disk)

#深拷贝
computer3=copy.deepcopy(computer)
print(computer,computer.cpu,computer.disk)
print(computer3,computer3.cpu,computer3.disk)


78.模块

一个模块中可以包含N多个函数

使用模块的好处:方便其他程序和脚本的导入并使用,避免函数名和变量名冲突,提高代码的可维护性,提高代码的可重用性

在python中一个扩展名为.py的文件就是一个模块——函数,类,语句


79.自定义模块和模块的导入

创建模块:新建一个.py文件,名称尽量不要与Python自带的标准模块名称相同

导入模块:

import  模块名称  [as 别名]

from  模块名称  import  函数/变量/类

import math#数学运算

print(id(math))
print(type(math))
print(math)

print(math.pi)
print('-----------------')
print(dir(math))
from math import pi
print(pi)

print(pow(2,3))#报错,你只是导入math里的pi,你并没有导入math

自己定义的模块导入

#calc.py

def add(a,b):

    return a+b

def div(a,b):

    return a/b

#如何区导入自定义模块
#导入calc自定义模块使用
import calc

print(calc.add(10,20))

print('-'*30)

from calc import add
print(add(10,20))

80.以主程序形式运行

在每个模块的定义中都包括一个记录模块名称的变量__name__,程序可以检查该变量,以确定他们在哪个模块中执行。如果一个模块不是被导入到其他程序中执行,那么它可能在解释器的顶级模块中执行。顶级模块的__name__变量的值为__main__

#calc2.py

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


print(add(10,20))
import calc2
print(calc2.add(100,200))

#30
 300
#calc2

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



if __name__=='__main__'  #主程序时运行
    print(add(10,20))    #只有当点击calc2时,才会被执行运算

81.python中的包

包是一个分层次的目录结构,它将一组功能相近的模块组织在一个目录下

作用:代码规范,避免模块名称冲突

包与目录的区别:

包含__init__.py文件的目录称为包

目录里通常不包含_init__.py文件

python程序:包 , 包里面又有好多模块 

包的导入:    import 包名.模块名

#在demo8的模块中导入pageage1包

import pageage1.module_A
print(pageage1.module_A.a)

print('等同')

import pageage1.module_A as ma #别名
print(ma.a)

导入带有包的模块时注意事项

import pageage1

import calc

#使用import方式进行导入时,只能跟包名或模块名




from pageage1 import module_A
from pageage1.module_A import a
#使用from...import可以导入包,模块,函数,变量

82.常用的内置模块

83.编码格式

python解释器使用的是Unicode(内存)

.py文件在磁盘上使用UTF-8存储(外存)

 84.文件的读写原理

文件的读写俗称“IO操作”  ——(input,output)——先进先出(管流)

.py文件——>解释器去执行——>调用OS操作系统的资源——>操作硬盘

内置函数open()创建文件对象——通过IO流将磁盘文件

通过IO流将磁盘文件中的内容与程序中的对象中的内容进行同步

file=open(filename ,[mode,encoding])——mode打开模式默认为只读,encoding——默认文本文件中字符的编写格式为gbk

r-读

file=open('a.txt','r')
print(file.readlines())  #结果是一个列表
file.close()

85.常用的文件打开模式

文件的类型

文本文件:存储的是普通“字符”文本,默认为unicode字符集,可以使用记事本程序打开

二进制文件:把数据内容用“字节”进行存储,无法用记事本打开,必须用专用的软件打开,例如"mp3音频文件,jpg图片,.doc文件"

打开模式描述
r以只读模式打开文件,文件的指针将会放在文件的开头
w以只读模式打开文件,荣光文件不存在则创建,如果文件存在,则覆盖原有内容,文件的指针将会放在文件的开头
a以追加模式打开文件,如果文件不存在则创建,文件指针在文件的开头;如果文件存在,则在文件末尾追加内容,文件指针在原文件末尾
b以二进制方式打开文件,不能单独使用,需要与其他模式一起使用,rb或者wb
+以读写方式打开文件,不能单独使用,需要与其他模式一起使用,a+

   

src_file=open('logo,png','rb')#读
target_file=open('copylogo.png','wb')#写

target_file.write(src_file.read())
target_file.close()
src_file.close()

86.文件对象的常用方法

方法名说明
read([size])从文件中读取size个字节或字符的内容;若省略[size],则读取到文件末尾,即一次读取文件所有内容。
readline()从文本文件中读取一行内容
readlines()把文本文件中的每一行都作为独立的字符串对象,并将这些对象放入列表返回
write(str)将字符串str内容写入文件
writelines(s_list)将字符串列表s_list写入文本文件,不添加换行符
seek(offse,[whence])

把文件指针移动到新的位置

offset表示相对于whence的位置:

offset:为正往结束方向移动,为负往开始方向移动

whence不同值代表不同含义

0从文件头开始计算(默认值)
1从当前位置开始计算
2从文件尾开始计算

tell()返回文件指针的当前位置
flush()把缓冲区的内容写入文件,但不关闭文件
close()把缓冲区的内容写入文件,并关闭文件,释放文件对象相关资源
file=open('a.txt','r')
print(file.read())

print(file.readlines())
file.colse


file=open('c.txt','a')
file.write('懒羊羊')
lst=['懒羊羊','喜羊羊','沸羊羊']
file.write(lst)
file.close()
file=open('a.txt','r')
file.seek(2)  #一个中文占两个字节
print(file.read())
print(file.tell())
file.close

with语句可以自动管理上下文资源,不论什么原有跳出with块,都能确保文件正确的关闭,以此达到释放资源的目的

with open('a.txt','r') as file:
    print(file.read())



# open('a.txt','r') 上下文表达式:结果是上下文管理器

 lyy实现了特殊方法__enter__(),__exit__()称为该类对象遵守了上下文管理器协议,该类对象的实例对象,称为上下文管理器

with lyy() as file:   相当于file=lyy()

        file.show()

with open('logo.png','rb')as src_file:
    with open('copy2logo.png','wb') as t_file:
        t_file.write(src_file.read())

87. 目录操作:

os模块时python内置的与操作系统功能和文件系统相关的模块,该模块中的语句的执行结果通常与操作系统有关

import os

#os模块与操作系统相关的一个模块
os.system('noteoad.exe')#打开记事本
os.system('calc.exe')#打开计算器

#直接调用可执行文件
os.startfile("D:\\Tencent\\QQ\\Bin\\QQ.exe")
函数说明
getcwd()返回当前的工作目录
listdir(path)返回指定路径下的文件和目录信息
mkdir(path,[mode])创建目录
mkdirs(path1/path2...,[mode])创建多级目录
remdir(path)删除目录
removedirs(path1/path2...)删除多级目录
chdir(path)将path设置为当前工作目录
import os
print(os.getcwd())

#C:\Users\hff\PycharmProjects\untitled15

lst=os.listdir('../chap15')  #..返回上级目录
print(lst)

os.mkdir('lyy')
os.makedirs('A/B/C')#在当前文件夹下创建A,A里有B,B里有C

os.removedirs("A/B/C")#删除A/B/C

88.os.path模块操作目录相关函数

函数说明
abspath(path)用于获取文件或目录的绝对路径
exists(path)用于判断文件或目录是否存在,如果存在——True
join(path,name)将目录与目录或者文件名拼接起来
splitext()分离文件名和扩展名
basename(path)从一个目录中提取文件名
dirname(path)从一个路径中提取文件路径,不包括文件名
isdir(path)用于判断是否为路径
import os.path
print(os.path.abspath('data6.1.py'))
print(os.path.exists('data3.py'))
print (os.path.join('D:\\Python','data2.py'))
print(os.path.split("D:\\Python\\data2.py"))
print(os.path.splitext("data2.py"))
print(os.path.basename('D:\\Python\\data2.py'))
print(os.path.dirname('D:\\Python\\data2.py'))
print(os.path.isdir('D:\\Python\\data2.py'))#data2.py这是一个文件

——————————————————————————————————————————————————————————
D:\Python\data2.py
('D:\\Python', 'data2.py')
('data2', '.py')
data2.py
D:\Python
False

#获取指定目录下面所有的python文件
import os
path=os.getcwd()
lst=os.listdir(path)
for filename in lst:
    if filename.endswith('.py'):
        print(filename)

import

#import module_a #导入
#from module import xxx #导入某个模块下的某个方法或者子模块 eg:os.system(‘df-h’)
#from module.xxx.xx import xx as rename #导入一个方法后重命名
#form module.xxx.xx import * #导入一个模块下的所有方法,不建议使用,直接eg:system(‘df-h’),容易和函数名冲突

python换行  空格+\ 回车

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值