1.在一个文件中打开另一个文件,如何实现同时读写?
之前说过先用open在本文件中打开另一个文件,如果不修改mode的值,那么默认就是r模式,即阅读模式,不能写入。还有w模式(只要一写入,之前写的就会被覆盖)和a模式(写入不会把前面的内容覆盖,而是紧跟在之前内容的后面),都是表示写入,但是在该过程中就不能再阅读里面的内容了。
例如:
在默认r模式的前提下想去写入:
f = open("info.txt",encoding = 'utf-8')
print(f.read())
f.write('你也是')
f.close()
结果:
因为先执行print函数,所以文件中的内容会先被打印出来,但是当后面尝试去写入时,就会报错,因为r模式不支持读的同时再写
在w模式的前提下想去读取:
f = open("info.txt",mode = 'w',encoding = 'utf-8')
f.write('你也是')
print(f.read())
f.close()
结果:
会先在 info.txt 文件中输入 你也是 这个内容,但是当程序运行到想要去阅读时,系统就会报错,因为w模式也不支持写的同时再读 (a模式与w模式一致)
那么如何实现同时读写呢?
如果想在读取时同时写入,将模式改为 r+ 即可,但是要注意该模式下是有先后顺序的,r+就要先读取再写入,如果违反了这个顺序,写入的内容会覆盖掉之前文件中的内容
正常情况下:
f = open("info.txt",mode = 'r+',encoding = 'utf-8')
print(f.read())
f.write('你也是')
f.close()
会先读取info.txt的内容:我是一个大美女 ,然后再在里面加入 你也是 的内容
顺序错了的情况:
f = open("info.txt",mode = 'r+',encoding = 'utf-8')
f.write("哈")
print(f.read())
f.close()
原本文件里是写着: 我是一个大美女
结果: 是一个大美女
因为write放在了read前面, 哈 把 我 给替代了,而且不会被打印到屏幕上,但是info.txt文件中,已经变成了 哈是一个大美女 。假如写入的字数超过文件中的,就不会打印出任何东西,它会把info.txt文件中的内容全部覆盖掉
例如:
f = open("info.txt",mode = 'r+',encoding = 'utf-8')
f.write("不喜欢早起啊啊啊")
print(f.read())
f.close()
结果:
代码执行,但不会打印任何东西,但是info.txt文件中内容不再是 我是一个大美女 ,内容变成了 不喜欢早起啊啊啊
如果想要在写入的同时进行读取,可以使用w+或者a+,也是有先后顺序的,先写再读。如果先读取再写入,即使打印读取的内容,在屏幕上不会打印出任何的东西,但是info.txt文件中的内容就会改变,w+每一次写入都是新的,a+每次都是挨着前一次增加
f = open("info.txt",mode = 'a+',encoding = 'utf-8')
print(f.read())
f.write("不喜欢早起")
f.close()
控制台上不会打印任何东西
原本info.txt文件中是 我是一个大美女,但是现在操作后就变成 我是一个大美女不喜欢早起
2.路径处理
1.如何 在本文件 打开 不是属于 本文件上一级文件 的另外文件?
例如:在 听课作业.py 中打开 into.txt
file = 'into.txt'
f = open(file,encoding = 'utf-8')
f.read()
f.close()
结果:报错,因为 听课作业.py文件的上一级文件day1_try中没有into.txt文件,无法通过文件名称找到
如果操作与同一个上一级文件的引入一样,那么会出错,因为上一级里面并不包括into.txt文件。相当于两个家庭,每一个家庭都有父母,都可以有多个孩子,在一个家庭中不能找到另一个家庭的孩子
如果想打开into.txt文件,那么就要去获得该文件的绝对路径。获得文件绝对路径的方式:右击文件名,里面有一个复制文件路径,使用ctrl+shift+c就可以复制,然后把file里面改成路径而不是名字,就可以打开了
假设在into.txt文件中有一行文字:哈哈哈
file = 'D:\python\My_Code\day 1\day2_try\into.txt'
f = open(file,encoding = 'utf-8')
print(f.read())
f.close()
结果: 哈哈哈
通过了此方式打开了into.txt文件,并打印了文件中的内容
相当于一个家庭通过某种特定的方式带另一个家庭的孩子到自己家里,那么在自己家里就能找到另一个家庭的孩子
还有一个值得注意的地方:
因为路径和转义字符都会使用到 \ 假如当 \后面的名字以n , t开头,那么会使路径不对,程序就会报错
如果想避免这个问题,应该在引号前面加一个r,即:
这样对内容没有任何的影响,又避免了转义
在Windows下,所有的路径表示都在前面加上r
上述的方式路径是固定的,假如把文件换到另一个路径,那么想再一次打开,因为路径已经变了所以就会打不开
接下来就会讲到python的三种操作路径:
1.如何通过python获取当前文件的路径
首先导入pathlib,然后再获取路径,因为获得的是绝对路径,所以后面要加上absolute:
import pathlib
a = pathlib.Path(__file__).absolute()
print(a)
这样就可以获得当前目录的路径,以路径的类型在计算机中存储
还有一种方式也可以获得当前目录的路径,但是类型是字符串,并不是以路径的类型在计算机中存储,不利于后续的处理,因为后续可能会进行路径的拼接等的操作,字符串形式的话就无法进行以下的操作,所以说还是要使用pathlib在外面包裹一层,表示一个对象。
print(__file__)
打印出的结果与前面一样,但是类型是完全不一样的,一般不使用这种方式
2.如何通过路径获得父级目录
通过路径获得父级目录是在获得当前文件的基础上加上 .parent
import pathlib
a = pathlib.Path(__file__).absolute()
print(a.parent)
这样就可以获得父级目录的路径从而找到父级目录
3.如何获得下一级目录
想获得下一级目录,可以使用路径的拼接
假如下一级与本文件是是同一个父级目录,可以在获得父级目录的基础上加上一个 / 然后后面加上引号,引号里面写上文件的名称,这样就可以获得下一级目录。如果不是同一个父级目录,就使劲往上找,直到到同一个目录中,然后进行一样的操作,但是对于这种情况来说,可以是到父级的父级才相同,甚至更多,所以说写的时候还要加上 / 和父级的名称,再写上目标文件的名称
关于iterdir
iterdir函数是用来遍历文件夹,所以可以利用此功能去打印文件夹中所包含的文件:
import pathlib
a = pathlib.Path(__file__).absolute()
for e in a.parent.iterdir():
print(e)
结果:
D:\python\My_Code\day 1\day1 _try\cases.txt
D:\python\My_Code\day 1\day1 _try\info.txt
D:\python\My_Code\day 1\day1 _try\听课作业.py
3.模块和包
模块:module 一个python文件就是一个模块
包:package 打包的意思 多个python文件集合在一起构成一个包
模块和包的命名规则与变量的命名一致
模块和包的作用:用来组织代码
一个包建立的时候,都会自动建一个 _ init _.py文件,所以说看到这个就要知道这是一个包
在一个模块中要想使用另一个模块中的代码就要先导入,导入有两种方式:
第一种:from…import
第二种:import (import 后面直接加导入的模块名称)
第一种使用较多,第二种使用较少
使用from…import导入:
第一种情况,比如在同一个目录下(所有目录都相同)的模块之间的导入,例如在 听课作业.py 中导入 模块与包.py 的代码,他俩是在一起的,导入的时候就之接写上被导入的模板的名字就行(写在from后面,import前面),import后面写被引入的内容名称:
from 模块与包 import add2
print(add2())
这样就可以在 听课作业.py 这个模块中获得 模块与包.py 这个模块里面的add2函数
第二种情况,有几个大目录相同,但是有一个目录不同,例如图中的 听课作业.py 与测试模块.py ,如果想在 听课作业.py 中导入 测试模块.py 的代码就不能像上面一样的操作,直接写上被导入模块的名字,因为不在一个包里面,如果这么写了就会报错。
from day1.day1_try1.测试模块 import win
win()
不同包的就要从项目目录开始找,因为 测试模块.py 的项目目录是从 day1开始的,所以就要一层一层的写出来
第三种情况,两个模块连项目模块都不同,例如 听课作业.py 与 day2模块和包.py ,想要在 听课作业.py 中打开 day2 模块和包.py 需要一层一层的写:
from day2.day2_try.day2模块和包 import add
add()
**值得注意的一个小点,我的错点:**在取目录名的时候在day和数字之间加入了一个空格,这样的话不管后面的步骤如何对都会报错,因为系统会将数字与点号放一起,就只剩下day了,所以会报错。所以取名时要注意
在pycharm
中可以设置临时源代码根目录,设置的方式是:右击文件名,点击最后一行 将目录标记为 ,直接点击设置临时源代码根目录
也可以取消。设置临时源代码根目录的用处:当前面有很多很多的目录,比较麻烦时,可以使用这个操作将中间某个目录设置为临时的,就可以不用从头开始写,会方便很多。但是这个操作只能用在一个目录上,不能被多次用
还是以上面的图片项目为例:在 听课作业.py 中获取 day2模块和包.py ,可以先将day2设置为临时源代码根目录,然后再从day2的下一级目录开始
from day2_try.day2模块和包 import add
add()
这样可以缩短引入的内容
PS:如果想要导入变量也是可以的,直接模块名加上变量名
from 模块与包 import text
print(text)
这就是在 听课作业.py 中导入 模块与包.py 的内容
还有一些函数以及包都是python系统自带的,这些叫做库,这就要我们自己去不断积累,再用import导入,或者用from…import
import一般是导入一整部分,from…import一般是从文件中获取某一代码
如何获取并安装内置库?
第一种方式:在python的命令行中输入 pip install 库名
第二种方式:找到设置–找到项目–打开Python解释器–点击加号–输入想要添加的库名称–直接添加(不用勾选别的)
如果说在导入的模块中的函数与自己本文件的一个函数的名称冲突该怎么办?
如果冲突,代码会执行自己的函数内容
有两种解决方式:
第一种:把自己本身的函数名改了
第二种:如果说自己的函数名已经在很多的地方被使用了,不好改的话就应该对引用的函数进行重命名
重命名的方法,在import 函数名后面加上 as 和新的函数名
如何调用一个模块中的所有函数?
from 目录路径 import *
在后面加 * 就可以调用所有的函数,如果调用的与自己本身有的起了冲突,就是说名字重复了,那么调用的那个就不会被执行,就会执行自己的代码