python阶段学习总结
文章目录
- python阶段学习总结
- 1、序列类型(列表 元组 字典 集合)
- 2、常见函数
- 3、运算符
- 4、字符串和正则表达式
- 5、面向对象
- 6、编码与文件操作
- 7、变量作用域
- 8、浅拷贝与深拷贝
- 9、模块
- 10、包(可以理解为文件夹,文件夹里面放了很多py文件,就是一个个模块)
1、序列类型(列表 元组 字典 集合)
列表 | 元组 | 字典 | 集合 | |
---|---|---|---|---|
名称 | list | tuple | dict | set |
符号 | [] | () | {} | {} |
是否可变 | 是 | 否 | 否 | 否 |
是否有序 | 是 | 是 | 否 | 否 |
支持下标 | 序号为下标 | 序号为下标 | 键为下标 | 不支持 |
内部元素分隔 | 逗号 | 逗号 | 逗号 | 逗号 |
元素形式要求 | 都可 | 都可 | 键值对 | 元素值不可改变 |
元素值的要求 | 都可 | 都可 | 键的值不可变 | 元素值不可变 |
元素是否可重复 | 可以 | 可以 | 键不可以重复 | 不可以 |
元素查找速度 | 非常慢 | 很慢 | 非常快 | 非常快 |
新增和删除元素速度 | 尾部操作快 | 不可增删 | 快 | 快 |
列表
- Python中内置有序、可变序列,列表的所有元素放在一对中括号“[]”中,并使用逗号分隔开
- 列表元素增加或删除时,列表对象自动进行扩展或收缩内存,保证元素之间没有缝隙
- 创建一个列表,只要把逗号分隔的不同的数据项使用方括号括起来即可
常用方法
方法 | 说明 |
---|---|
lst *= n | 更新列表lst, 其元素重复n次 |
lst.append(x) | 将元素x添加至列表lst尾部 |
lst.extend(L) 或lst += L | 将列表L中所有元素添加至列表lst尾部 |
lst.insert(index, x) | 在列表lst指定位置index处添加元素x,该位置后面的所有元 |
lst.remove(x) | 在列表lst中删除首次出现的指定元素,该元素之后的所有元素前移一个位置 |
lst.pop([index]) | 删除并返回列表lst中下标为index(默认为-1)的元素 |
lst.clear() | 删除列表lst中所有元素,但保留列表对象 |
lst.index(x) | 返回列表lst中第一个值为x的元素的下标,若不存在值为x的元素则抛出异常 |
lst.count(x) | 返回指定元素x在列表lst中的出现次数 |
lst.reverse() | 对列表lst所有元素进行逆序 |
lst.sort(key=None, reverse=False) | 对列表lst中的元素进行排序,key用来指定排序依据,reverse决定升序(False)还是降序(True) |
lst.copy() | 返回列表lst的浅复制 |
- 扩展列表
使用类似复制的方法
lst = ['mi', 'huawei', 'vivo', 'oppo']
print(lst*3) #变为三个字符串
- 给列表添加元素
直接使用+操作
lst = ['mi', 'huawei', 'vivo', 'oppo']
print(lst+['hfut']) #添加一个列表进入
这并不是真的为列表添加元素,而是创建了一个新列表,并将原列表中的元素和新元素依次复制到新列表的内存空间。如果列表很大的话,这个操作很花时间。
新增单个元素
lst = ['mi', 'huawei', 'vivo', 'oppo']
# print(lst.append('hfut')) #这种写法是错的,返回none
lst.append('hfut') # 这个不能被赋值,因为他是自己操作自己,单独一条语句即可
print(lst)
新增至少一个元素
lst = ['mi', 'huawei', 'vivo', 'oppo']
# print(lst.append('hfut')) #这种写法是错的,返回none
lst.extend(['hfut','lx2035']) # 注意,多个元素的时候要用括号抱起来
print(lst)
- 插入元素到列表
lst = ['mi', 'huawei', 'vivo', 'oppo']
# print(lst.append('hfut')) #这种写法是错的,返回none
lst.insert(2,'lx2035') # 注意是从0开始
print(lst)
- 下标操作
lst = ['mi', 'huawei', 'vivo', 'oppo','huawei']
print(lst[1]) #下标索引,注意是需要中括号
使用下标进行索引
正向索引
反向索引
截取索引
lst = ['mi', 'huawei', 'vivo', 'oppo','huawei']
print(lst[1]) #下标索引,注意是需要中括号
print(lst[-4])
print(lst[1:2]) #注意截取是个列表,我这样是一个元素的列表
使用下标进行各种切片 list[start_index: stop_index: step] 起始位置 结束位置 步长
lst = ['mi', 'huawei', 'vivo', 'oppo','huawei']
print(lst[::]) # 全部缺省,等于没切
print(lst[1:]) #从1开始
print(lst[::-1]) #等效逆序
print(lst[::2]) #偶数位置
print(lst[1::2]) #奇数位置
lst[:2] = ['lx2035','lx2035'] #替换前两个
print(lst)
- 删除指定元素
lst = ['mi', 'huawei', 'vivo', 'oppo','huawei']
del lst[0] #使用del命令删除
print(lst)
lst.remove('huawei') #使用remove移除,移除这个值的第一个匹配项
print(lst)
lst.pop(-2) #使用pop移除, 按照索引来移除项,默认是-1
print(lst)
- 删除所有元素
lst = ['mi', 'huawei', 'vivo', 'oppo','huawei']
del lst #列表都没了,从内存消失
print(lst)lst = ['mi', 'huawei', 'vivo', 'oppo','huawei']
lst.clear() #变为空列表
print(lst)
- 元素出现次数
列表是可重复的,故而这样就是没啥问题,操作如下
lst = ['mi', 'huawei', 'vivo', 'oppo','huawei']
print(lst.count('huawei')) #出现两次
- 逆序
lst = ['mi', 'huawei', 'vivo', 'oppo','huawei']
lst.reverse()
print(lst)
- 排序
下面有专门说排序的。这里略过(sort和sorted函数)
- 浅复制
lst = ['mi', 'huawei', 'vivo', 'oppo','huawei']
lst1 = lst.copy()
print(lst1)
列表平铺
[[[1,2,3], [4,5,6]]] -> [1, 2, 3, 4, 5, 6]
lst = [[1,2,3],[4,5,6]]
result = []
for item in lst:for num in item:result.append(num)print(result)
# 使用sum函数
lst = [[1,2,3],[4,5,6]]
lst_new = sum(lst,[]) #不会改变原列表
print(lst_new)
sum是用来对序列求和的,这样就相当于每个元素都加0,就保持了自己的原样
# 使用
lst = [[1,2,3],[4,5,6]]
lst_new = [num for item in lst for num in item]
print(lst_new)
元组
- 元组一旦定义就不允许更改
- 不可进行增删改等操作
- 使用tuple函数变其他为元组(列表集合什么的)
zip函数:将可迭代的对象作为参数打包为元组,然后形成这些元祖组成的列表
a = [1,2,3]
b = [4,5,6]
c = [2,5,7]new = zip(a,b,c)
print(list(new)) #注意这个返回的是一个对象,如果要变成列表,要lst转换
a = [1,2,3]
b = [4,5,6]
c = [2,5,7]new = zip(a,b)
lst1 = zip(*new)
print(list(lst1)) #逆操作
这里注意是每个可变序列的元素一一匹配,就是第一个和第一个,第二个和第二个这种的,匹配次数很据短的来定
直接使用tuple函数
a = tuple() #空元祖print(tuple('abcdefg')) #字符串转为元祖
只有一个元素的时候,要在元素后面添加,不然当成一个数据
tup = (50) #50就是一个整形数据
tup1 = (50,) #是只有一个元素的元祖
访问元祖
还是下标索引
tup1 = (12, 34 ,56)
tup2 = ('abc', 'xyz')#注意不能修改下标,元祖是不能修改的print(tup1[0],tup1[1:2]) #注意后面一个返回的是一个新的元祖
注意,元祖不可修改是元素不可增删改,但是可以进行拼接
tup1 = (12, 34 ,56)
tup2 = ('abc', 'xyz')#注意不能修改下标,元祖是不能修改的print(tup1+tup2) #拼接
最值查找
tup = (12, 34 ,56)
lst = (12,45,85)#注意不能修改下标,元祖是不能修改的print(max(tup),max(lst)) #拼接
print(min(tup),min(lst)) #拼接
字典
- 字典是无序的,打印就知道不会按照你写的那样排
- 键值对,写的时候要规范
创建字典
访问字典里的值
修改字典
集合
- 无序不可变序列,不可重复,每个元素都是唯一的
- 集合中不能有可变的数据
创建空集合必须用set而不是{},因为这会和字典冲突
set0 = set() #创建了一个空集合
set1 = {'mi','huawei','oppo','vivo'} #创建集合,和列表非常像
set2 = set('asffasfagasd')
print(set2)
集合之间的运算(跟数学好像是一样的)
a = set('asffasfagasd')
b = set('fsafasfsd')
print(a-b) # a有b没有
print(a|b) # ab中的所有
print(a&b) # ab都有的
print(a^b) # 不同时在ab之中的
集合添加元素
set1 = {'mi','huawei','oppo','vivo'} #创建集合,和列表非常像
set1.add('lx2035')
print(set1)
添加可变序列
set1 = {'mi','huawei','oppo','vivo'} #创建集合,和列表非常像
set1.add('lx2035') #注意不能是已经有了的,不然没意义
print(set1)
set1.update(['fsfd','fsadfd']) #添加可变序列
print(set1)
删除元素
set1 = {'mi','huawei','oppo','vivo'} #创建集合,和列表非常像
set1.remove('mi') #元素不存在会报错
print(set1)
set1.discard('mi') #元素不存在不会报错
print(set1)
set1.pop() #因为集合是无序的,所以是随机删除
print(set1)
2、常见函数
- map函数
会根据提供的函数对指定序列做映射,类似遍历
def square(x):return x**2print(map(square,[1,2,3,4])) # 返回迭代器地址
print(list(map(square,[1,2,3,4])))print(list(map(lambda x:x**2,[1,2,3,4]))) #使用匿名函数,结果相同
有多个参数的时候,按照元素数目最少的来算
listx = [1,2,3,4,5,6,7] # 7 个元素
listy = [2,3,4,5,6,7] # 6 个元素
listz = [100,100,100,100] # 4 个元素
list_result = map(lambda x,y,z : x**2 + y + z,listx, listy, listz)
print(list(list_result))
还可用于批量对列表字符串处理
name_list={'tony','cHarLIE','rachAEl'}
def format_name(s):ss=s[0:1].upper()+s[1:].lower();return ss;
print (list(map(format_name,name_list)))
可以看出函数是对字符串的第一个大写,最后一个变小写,使用map函数对其中所有字符串一起操作
- eval函数
执行一个字符串表达式,并返回表达式的值,相当与计算字符串里的式子
x = 7
print(eval('x*3')) # 直接计算
print(eval('pow(2,2)')) # 内置函数计算
就是返回他自己认为正确的值,比较有意思的是可以从输入返回数字
45
a,b = eval(input())
print(a,b,type(a),type(b))这里我输入45,56.7 就能自动给ab,并且用int和float的形式保存
输入的是数字才行,这样直接转化为数字计算,不然字符串什么的计算不了,会报错
但是int(input()) 输入小数的话小数直接没有,因为就算是强制类型转换也会丢掉小数
比如
print(int(5.65)) #输出5
保留小数的方法:内置函数round
# 保留指定位数的小数
print(round(3.1415926,1))
print(round(3.1415926,2))
print(round(3.1415926,3)) #遵循四舍五入
print(round(3.1415926)) #小数位数不填就是整数
这里在补充一下计算不精确的问题,描述如下
print(0.1+0.2) #结果不是0.3
print((0.1+0.2) == 0.3) #显然结果为False
原因好像是计算机用二进制计算,计算后有返回,中间有数据省略,就像我们做大计算的时候,结果是多个结果的累加的时候不要一个个算出来四舍五入在相加,这样累计四舍五人几次的误差也就挺大。
要解决这样的问题
- 使用范围,就是两者误差小于一定值就认为相等
- 使用decimal函数,具体如下:
from decimal import Decimal
print(Decimal(0.125)+Decimal(0.125)) #结果为0.250
- 使用格式化字符串的方法
print('{0:.2f}'.format(0.125)) #直接保留,没有四舍五入,这里是两位小数
- divmod函数
把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b)
print(divmod(7,2)) #返回7、2的商和余数
- sort sorted函数
对原列表进行排序,如果指定参数,则使用比较函数指定的比较函数
aList = ['mi', 'huawei', 'vivo', 'oppo']aList.sort()
print (aList) #注意这里是源列表重新排,改变源列表了已经
对列表元素直接排,是按照首字母排序
aList = ['mi', 'huawei', 'vivo', 'oppo']aList.sort(reverse=True) #指定降序排列
print (aList)
下面进行指定元素排列
def getsecond(lst):return lst[1]aList = ['mi', 'huawei', 'vivo', 'oppo']aList.sort(key=getsecond,reverse=True)
print (aList)
有点意思的数字和字符串一起排序
lst = [-1, -3, 1, 0, 3, 'a', 'b', 'c']
lst.sort(key = str) #全部转成字符串
print(lst) #先排数字,字符串后面排
与sort相比,sorted函数会产生一个新的排序列表,不会改变原来的列表
递归函数
函数体内部调用函数本身,就是递归,优点是思路和代码简单,缺点是占用内存多,效率低(调用一次函数就会创建一个堆栈)
使用递归计算阶乘
def fac(n):if n==1:return 1else:return n*fac(n-1)
print(fac(6))
斐波那契数列
def fib(n):if n==1:return 1elif n==2:return 1else:return fib(n-1)+fib(n-2)for i in range(1,7):print(fib(i))
try-except尝试
try没问题就是else的内容,不然就是except的内容
try:a = int(input('输入第一个数'))a = int(input('输入第二个数'))result = n1/n2
except BaseException as e:print('出错了')print(e)
else:print('结果为',result)
finally:print('无论如何都执行')
常见异常
异常 | 描述 |
---|---|
Zero Division Error | 除0 |
IndexError | 序列中没有这个索引 |
KeyError | 映射中没有这个键 |
Name Error | 未声明对象 |
SyntaxError | 语法错误 |
Value Error | 传入无效参数 |
打印异常信息
import traceback
try:print(1/0)
except:traceback.print_exc()
3、运算符
运算符 | 表示 |
---|---|
算术运算符 | +、-、*、/、//、%、** |
关系运算符 | >、<、==、<=、>=、!= |
测试运算符 | in、not in、is、is not |
逻辑运算符 | and、or、not |
位运算符 | ~、&、 |
矩阵乘法运算符 | @ |
4、字符串和正则表达式
Python 3完全支持中文字符,默认使用UTF8编码格式,无论是一个数字、英文字母,还是一个汉字,在统计字符串长度时都按一个字符对待和处理
str = '字符串'
str1= '字符串2020'
姓名 = 'lx2035'print(str,str1,姓名)
字符串常用操作
操作 | 含义 |
---|---|
+ | 连接 |
* | 重复 |
[],index(),rindex() | 索引 |
[::] | 剪切 |
len | 长度 |
upper(),lower() | 字符串字母大小写 |
capitalize(),title(),swapcase() | 首字母大写 |
strip() | 去两边空格及指定字符 |
spilt(),rsplit(),lstrip() | 按照指定自负分割 |
join() | 连接 |
find(),rfind() | 搜素 |
replace() | 替换 |
for in | 迭代 |
startswitch(),endswitch(),··· | 对齐 |
访问字符串
# 引号来创建字符串
str1 = 'lx2035-helloworld'#访问字符串
print(str1[0],str1[1:5])
# 引号来创建字符串
str1 = 'lx2035-helloworld'# 修改字符串
str1 = str1[1:5]+'aaa'
print(str1)
字符串格式化
%c | 格式化字符及其ASCII码 |
---|---|
%s | 格式化字符串 |
%d | 格式化整数 |
%u | 格式化无符号整型 |
%o | 格式化无符号八进制数 |
%x | 格式化无符号十六进制数 |
%X | 格式化无符号十六进制数(大写) |
%f | 格式化浮点数字,可指定小数点后的精度 |
%e | 用科学计数法格式化浮点数 |
%E | 作用同%e,用科学计数法格式化浮点数 |
%g | %f和%e的简写 |
%G | %f 和 %E 的简写 |
%p | 用十六进制数格式化变量的地址 |
辅助指令
* | 定义宽度或者小数点精度 |
---|---|
- | 用做左对齐 |
+ | 在正数前面显示加号( + ) |
sp | 在正数前面显示空格 |
# | 在八进制数前面显示零(‘0’),在十六进制前面显示’0x’或者’0X’(取决于用的是’x’还是’X’) |
0 | 显示的数字前面填充’0’而不是默认的空格 |
% | ‘%%‘输出一个单一的’%’ |
(var) | 映射变量(字典参数) |
m.n. | m 是显示的最小总宽度,n 是小数点后的位数(如果可用的话) |
print ("我叫 %s 今年 %d 岁!" % ('小明', 10))
使用format函数基本语法是{}和:来代替%
print('{}{}'.format('hello','world'))
print('{1}{0}'.format('hello','world')) #指定位置
print('{:.2f}'.format(3.1415926)) #格式化字符串
5、面向对象
面向对象-类
- 多个类似事物的统称,具有一些共性(帮助人们快速理解事物)
- 不同的数据类型属于不同的类(整形,浮点,字符等)
面向对象-对象
- int对象为例,9,100,65都是一个个对象,##1、面向对象-类
编写对象
class开头,对象名大写
class Student:pass
print(id(Student)) #内存空间
print(type(Student)) # 类型
print(Student)# 内容
类方法
注意,类之内的是方法,之外的叫函数
class Student:native_pace = '吉林' #类属性def __init__(self,name,age): # 初始化方法self.name=name #实例属性self.age=agedef eat(self): # 类的实例方法print('在吃饭')@staticmethod # 静态方法def method():print('静态方法')@classmethod # 动态方法def cm(cls):print('动态方法')
使用类
stu1 = Student('张三',20)
stu1.eat()
print(stu1.name)
print(stu1.age)Student.eat(stu1) # 这个和上面的是等效的
修改
stu1 = Student('张三',20)
stu2 = Student('李四',30)print(Student.native_pace)
print(stu1.native_pace)
print(stu2.native_pace)
Student.native_pace = '天津'
print(stu1.native_pace)
print(stu2.native_pace)
修改为天津后,两个都修改了(两个student的实例对象都修改了,类指针指向原类别,所以一个变两个都变)
静动态方法使用
stu1 = Student('张三',20)
stu2 = Student('李四',30)print(stu1.method())
print(stu1.cm())
直接使用方法名进行访问
动态绑定属性和方法
class Student:def __init__(self,name,age):self.name = nameself.age = agedef eat(self):print(self.name+'在吃饭')stu1=Student('张三',20)
stu1=Student('李四',20)stu1.gender = '女'
print(stu1.gender) #给对象绑定属性
stu1.eat() # 本身的方法def show():print('我是要添加的方法')
stu1.show = show
stu1.show()
注意哦,函数和方法不一眼的,而且这两个是只对stu1操作的,与stu2无关
4、面向对象的三大特征
特征 | 含义 |
---|---|
封装 | 提高程序的安全性,就是把属性和行为封装到类里面 |
继承 | 提高代码的复用性 |
多态 | 提高程序的可扩展和可移植性 |
封装
封装一个汽车对象
class Car:def __init__(self,brand):self.brand = branddef start(self):print('汽车已启动。。。')car = Car('宝马x5')
car.start()
print(car.brand)
class Student:def __init__(self,name,age):self.name = nameself.__age = age #加两杆就是让不容易被外面使用def show(self):print(self.name,self.__age)stu=Student("张三",20)
stu.show()
print(stu.name)
print(stu.age) # 这个会报错,原因见上文print(dir(stu)) # 查看所有属性
print(stu._Student__age) #从所有属性里面看来的,这样可以实现
继承
class Person(object):def __init__(self,name,age):self.name = nameself.age = agedef info(self):print(self.name,self.age)class Student(Person): # 继承def __init__(self,name,age,stu_no):super().__init__(name,age)self.stu_no = stu_noclass teachofyear(Person): # 继承def __init__(self,name,age,teachofyear):super().__init__(name,age)self.teachofyear = teachofyear
多继承
class A(object):passclass B(object):passclass C (A,B):pass
方法重写
class Person(object):def __init__(self,name,age):self.name = nameself.age = agedef info(self):print(self.name,self.age)class Student(Person): # 继承def __init__(self,name,age,score):super().__init__(name,age)self.score = scoredef info(self):super().info()print('学号:{0}'.format(self.score))class Teacher(Person): # 继承def __init__(self,name,age,teachofyear):super().__init__(name,age)self.teachofyear = teachofyeardef info(self):super().info() #继承了父类的方法print('教龄',self.teachofyear)stu = Student('张三',20,'1001')
teacher = Teacher('李四',50,'10')stu.info()
teacher.info()
obiect类
是创建一个类时候默认的方法
多态
动态语言的多态,不关心对象是什么类型,只关心对象的行为
class Animal(object):def eat(self):print('动物要吃东西')
class Dog(object):def eat(self):print('狗吃肉')
class Cat(object):def eat(self):print('猫吃鱼')
class Person(object):def eat(self):print('人吃五谷杂粮')def fun(obj):obj.eat()fun(Cat())
fun(Dog())
fun(Person())
5、特殊属性
class A(object):passclass B(object):passclass C (A,B):def __init__(self,name,age):self.name = nameself.age = age
x = C('Jack',20)
print(x.__dict__) #实例对象的属性字典
print(C.__dict__) # 这里打印了一个类对象的属性字典
print(x.__class__) #输出对象所属的类
print(C.__base__) #输出父类
print(C.__bases__)
print(C.__mro__) #类的层次结构
6、特殊方法
add len new init
a = 20
b = 100
c = a+b #两个整数类型的对象相加
d = a.__add__(b) #和上面等效print(c)
print(d)class Student:def __init__(self,name):self.name=namedef __add__(self,other):return self.name+other.namestu1 = Student('张三')
stu2 = Student('李四')s = stu1+stu2 # 在student类中编写了加的操作,必须是__add__
s = stu1.__add__(stu2) # 或者用这种方法
print(s)# 类似的还有len __len__(表示对象长度)
- new和init
class Person(object):def __new__(cls,*args,**kwargs):print('__new__败掉用了,self的id为:{0}'.format(id(self)))obj = super().__new__(cls)print('创建的对象id为:{0}'.format(id(obj)))return objdef __init__(self,name,age):print('__init__败掉用了,self的id为:{0}'.format(id(self)))self.name=nameself.age=ageprint('object类对象的id为:{0}'.format(id(object)))
print('Person类对象的id为:{0}'.format(id(Person)))
6、编码与文件操作
编码
python解释器上使用的编码是Unicode编码(内存)
.py文件在磁盘上使用的是utf-8的储存方式(外存)
如果要修改文件默认编码,在代码最上面添加
#encoding=gbk
注意,使用不同编码占用的磁盘空间(字节数不一样)
文件读写(io)
内置函数open()创建文件对象,这个是对磁盘中真实存在的文件的映射
语法规则 file = open(filename,[,mode,encoding]) 默认只读,文本编写格式默认gbk
file = open('1.txt','r',encoding='utf-8')#这里注意,我是用vscode创建的,默认是utf-8
print(file.readlines())
file.close()
如果是win创建,就是默认是gbk什么的,就不需要加上这个编码选定
注意这里读取每行返回的是列表
常用的文件打开方式
- 写模式
file = open('b.txt','w',encoding='utf-8')#这里注意,我是用vscode创建的,默认是utf-8
# 使用w,就是写,如果原来没有就创建
file.write('我爱你!!!')
file.close()
- 追加模式
file = open('b.txt','a',encoding='utf-8')#这里注意,我是用vscode创建的,默认是utf-8
# 使用w,就是写,如果原来没有就创建
file.write('我爱你!!!')
file.close()
在后面接着写
二进制文件:数据用字节储存,只能用二进制的方式读写
用法总结
函数名 | 用法 |
---|---|
read([size]) | 读取size个字节,若省略,全部读取 |
readline() | 读取一行内容 |
readlines() | 每一行都作为独立的字符串对象,并放入列表返回 |
wirte(str) | 字符串写入文本文件 |
writelines(s_list) | 字符串列表写入文本文件,不加换行 |
seek(offset[,whence]) | 文件指针移动位置 |
tell | 返回文件指针当前位置 |
flush | 缓冲区内容写入文件,但不关闭文件 |
close | 缓冲区的内容写入文件,同时关闭文件,释放文件对象的资源 |
file=open('b.txt','r',encoding='utf-8')
file.seek(2)
print(file.read())
file.close()
with语句
with open('a.txt','r',encoding='utf-8') as file:print(file.read())
class MY_TEST(object):def __enter__(self):print('enter被调用了')return selfdef __exit__(self,exc_type,exc_val,ext_tb):print('exit被调用了')def show(self):print('show方法被调用了')with MY_TEST() as file:file.show()
不管怎样,exit都会被执行
输出
使用printf进行输出
fp = open('test.txt','w')
print('奋斗成就更好的你',file=fp)
fp.close()
使用file读写
with open('test.txt','w') as file:file.write('奋斗成就更好的你')
目录操作
import os
path=os.getcwd() # 获取当前目录
lst=os.listdir(path) # 获取目录下所有文件
for filename in lst:if filename.endswith('.py'): # 判断是不是python文件print(filename)
7、变量作用域
局部变量
def fun(a,b):c = a+bprint(c)print(a)
print(c)
只在函数内部有效,作用范围函数内部,在外部调用都是错的
全局变量
name = 'lx2035'
print(name)
def fun2():print(name)fun2()
name在内部和外部都可以使用,是全局变量
使用global,变局部为全局
def fun(a,b):global cc = a+bprint(c)
fun(2,3) # 这里要执行下,不然还是没有c
print(c)
8、浅拷贝与深拷贝
一般是浅拷贝,没有特别说明就都是浅拷贝- 浅拷贝不拷贝子对象,只拷贝原对象
- 深拷贝则都拷贝,递推拷贝源对象的子对象,就是把基于这个原对象的所有子对象都拷贝掉
class CPU:pass
class Disk:pass
class Computer:def __init__(self,cpu,disk):self.cpu = cpuself.disk = diskcpu1 = CPU()
cpu2 = cpu1 #复制print(cpu1)
print(cpu2) # 结果相同disk=Disk()
computer = Computer(cpu1,disk)import copycomputer2=copy.copy(computer)#浅拷贝,结果还是相同print(computer,computer.cpu,computer.disk)
print(computer2,computer2.cpu,computer2.disk)
9、模块
模块包含
- 函数
- 类
- 语句
将一个项目分成多个模块有不同的人去开发,提高效率,第二是模块可以被多个项目复用
两个模块可以使用相同名称的变量,避免名称冲突,但是注意不要和系统的默认模块名字相同
def add(a,b):return a+bprint(add(10,20)) # 这个只要你调用了calc就会执行if __name__ == '__main__': #这个意思是,只有在执行calc的才会执行print(add(10,20))
10、包(可以理解为文件夹,文件夹里面放了很多py文件,就是一个个模块)
是一个分层次的目录结构,将一组功能相近的模块组织在一起
区别:
import 导入包名,模块名
from 导入包,模块,函数等