python常用标准库(os系统模块、shutil文件操作模块)

常用的标准库

系统模块

import os

系统模块用于对系统进行操作。

[En]

The system module is used to operate the system.

常用方法

os模块的常用方法有数十种之多,本文中只选出最常用的几种,其余的还有权限操作、文件的删除创建等详细资料可以参考官方文档。

system — 执行系统命令

参数的数据类型为字符串格式,内容为系统指令。执行时,直接返回系统输出。

[En]

The data type of the parameter is in string format and the content is the system instruction. When executed, the system output is returned directly.

import os

os.system('ifconfig')  # Linux系统shell命令
os.system('ipconfig')  # Windows系统dos命令
popen — 执行系统命令

在使用 system执行系统命令的时候,发现在windows系统下执行命令时,中文字符发生了乱码!这是因为windows为减少占用,对中文系统使用GB格式编码,而python中默认使用的UTF-8编码,编码不兼容导致了乱码问题。

popen也可以执行系统指令,但是和 system的工作方式不一样。

popen执行系统指令之后返回对象,通过内置方法 read读出字符串,这个过程中 read方法自动的将其它编码转换成为了UTF-8格式,所以 popen相比 system有更高的可读性和兼容性。

而在实际的使用过程中,发现popen不存在阻塞,即在执行一些长时间系统任务的时候,不会等待系统任务结束,python代码就会继续执行,在某些场景下会导致问题的出现。比如在我的一个场景中,要将一个文件夹中的文件删除,之后在重写一份文件,使用popen导致文件还没有删除,而代码继续执行使新文件已经写好,而这个时候popen又将我新写的文件删除,导致我的程序在后续出现bug。所以,如果没有可读性的要求,我建议优先使用system方法。

import os

obj = os.popen('ipconfig')
res = obj.read()
print(res)
listdir — 获取指定文件夹中的所有文件

获取指定文件夹中的所有文件(包括文件和文件夹),返回文件的名称,并将其作为列表返回,默认情况下使用当前路径。

[En]

Gets all files (including files and folders) in the specified folder, returns the name of the file, and returns it as a list, with the current path by default.

import os

默认为当前路径
files = os.listdir()
print(files)

可以使用相对路径和绝对路径<details><summary>*<font color='gray'>[En]</font>*</summary>*<font color='gray'>Both relative and absolute paths can be used</font>*</details>
files = os.listdir('C:')
print(files)
walk — 递归遍历目录

递归循环访问指定的目录,包括其所有子目录,并返回迭代器对象。迭代器一次返回一个元组,该元组由三个元素组成:

[En]

Recursively iterates through the specified directory, including all its subdirectories, and returns an iterator object. The iterator returns one tuple at a time, and the tuple is three elements:

  1. 第一个元素为字符串,表示当前目录路径;
  2. 第二个元素为列表,表示当前目录下的所有文件夹名(不包括子目录中的);
  3. 第三个元素为列表,表示当前遍历目录中的所有文件名(不包括子目录中的);

主要参数 含义 top 指定目录; topdown 正序遍历还是倒序遍历,默认为True(正序);

请看下面的示例。目录结构如下:

[En]

Take a look at the following example. The directory structure is as follows:

C:\USERS\MSR\DESKTOP\TEST
│root.txt
├─1
│  ├─1.txt
│  └─111
│     └─11.txt
└─2
   └─2.txt
import os

path = r'C:\Users\MSR\Desktop\test'

正序遍历
res = os.walk(path)  # 返回迭代器
for i in res:
    print(i)
r"""
('C:\\Users\\MSR\\Desktop\\test', ['1', '2'], ['root.txt'])
('C:\\Users\\MSR\\Desktop\\test\\1', ['111'], ['1.txt'])
('C:\\Users\\MSR\\Desktop\\test\\1\\111', [], ['11.txt'])
('C:\\Users\\MSR\\Desktop\\test\\2', [], ['2.txt'])
"""

逆序遍历(优先显示最深层的子目录)<details><summary>*<font color='gray'>[En]</font>*</summary>*<font color='gray'>Traversal in reverse order (give priority to showing the deepest subdirectories)</font>*</details>
res = os.walk(path, topdown=False)
for i in res:
    print(i)
r"""
('C:\\Users\\MSR\\Desktop\\test\\1\\111', [], ['11.txt'])
('C:\\Users\\MSR\\Desktop\\test\\1', ['111'], ['1.txt'])
('C:\\Users\\MSR\\Desktop\\test\\2', [], ['2.txt'])
('C:\\Users\\MSR\\Desktop\\test', ['1', '2'], ['root.txt'])
"""
getcwd — 获取当前工作路径
import os

获取当前的工作路径
dir_path = os.getcwd()
print(dir_path)  # E:\0-project\python\test

获取当前文件的路径
file_path = __file__  # 使用内置属性__file__获取
print(file_path)  # E:/0-project/python/test/test3.py

注意:getcwd()获取的使用当前工作路径,__file__是获取当前文件的路径

对于这个注意事项,大家一定要铭记于心,因为我被人欺骗了,当然这应该算是pycharm的坑吧!

注意了,文件的所在路径和工作路径是不相同的,文件的所在路径就是在系统中的这个脚本文件实实在在的地址,如果这个文件在 C:\下,那么在任何的情况下这个文件的所在路径都是 C:\;而工作路径不同,如果我们在 C:\下执行这个python文件,那么我们的工作路径就是 C:\,如果我们是在 D:\下执行,那么我们的工作路径就是 D:\,这就是文件所在地址和工作地址的区别,但是在一般情况下,我们执行文件都是在文件的所在地址执行的,所以大部分的时候文件所在路径和当前工作路径都是相同的。

可我在最开始学习这个方法的时候,我的老师教我说 getcwd()的作用是获取文件的所在路径,那么是什么让我一直以为 getcwd()的作用是获取文件的所在路径呢?是老师教给我的……感觉这个老师很不靠谱?那么老师怎么没有发现其中的含义呢?我怎么又一直深信不疑呢?我觉得这个一定是要pycharm来背锅了!我们在学习的时候一般都是相信自己的实际操作的结果的,我们执行的结果是什么,反复那么几次,我们的印象就会加深!

然后今天 2021&#x5E74;12&#x6708;7&#x65E5;20:58:09我在给公司的项目写一个启动脚本,目的是为了避免使用繁琐的命令去启动关闭项目,那么我在写的时候为了能够在系统的任何一个地方都是可以使用这个脚本,所以将命令中的各种路径全部写为绝对路径,我们系统工程师对绝对路径是非常熟练的!但是在我写好使用的时候就发现程序根本就启动不起来,已启动就死掉了,我就开始找原因,后来我发现在程序的目录下启动就没有问题,在其它的地址启动就有问题,我就意识到这是路径的错误。当然我们是有日志的,我看日志说是配置文件相关的地方出现了错误,我一看,就很好奇,配置文件是在程序的目录中的,读取的时候使用相对路径来获取,但是却没有读到文件,但是我检查之后文件是存在的!那么这个问题就很明显了,工作路径出了问题。

但是我还疑惑,为什么会影响到相对路径吗?然后我就测试了getcwd,发现果然如此,getcwd返回的不是文件的所在地址而是当前所在的工作地址,这个时候我还不死心,因为当时老师说的不是这样,所以我以为是linux和windows的差异,所以我就咋爱windows中又测试了一遍,发现还是一样的。那么我就又疑惑了,怎么在pycharm中,工作路径始终都是文件的所在路径呢?然后我就发现原来pycharm中可以指定文件的工作路径,而且默认将当前的文件路径作为工作路径使用。

python常用标准库(os系统模块、shutil文件操作模块)

然后我看文档介绍: Return a unicode string representing the current working directory.,emmm估计当时老师也是被pycharm坑了吧。所以大家以后如果想要在程序中固定工作路径,可以在启动文件中使用 __file__获取,或者使用 os.chdir方法。

然后最后还是在强调一下:工作路径会影响到相对路径的使用,但是不会影响到 sys.pathpython的环境变量。

chdir — 修改当前工作路径

之前我们有学过很多的函数,他们在涉及到路径的时候,一般默认情况都是当前脚本文件所在的目录(比如刚才的 listdirgetcwd),如果将文件的默认工作路径修改,就会影响到其它的一些功能,比如说我们导入文件使用相对路径等,所以,谨慎使用。

import os

在修改默认工作路径之前使用<details><summary>*<font color='gray'>[En]</font>*</summary>*<font color='gray'>Use before modifying the default work path</font>*</details>
print(os.getcwd())  # E:\0-project\python\test

chdir 修改当前文件工作的默认路径
os.chdir('C:')

在修改工作路径后使用
print(os.getcwd())  # C:\
access — 测试权限

用于测试一个指定路径或者文件的权限,返回True或者False。

语法:os.access(path, mode)

必要参数为path和mode,分别表示路径和测试的权限类型。

mode 说明 os.F_OK 是否存在; os.R_OK 是否可读; os.W_OK 是否可写; os.X_OK 是否可执行;

urandom — 随机字节对象

返回包含适合加密使用的随机字节的bytes对象。

import os

参数为字节长度
key = os.urandom(1)
print(key, len(key))
b'\x92' 1

key = os.urandom(5)
print(key, len(key))
b'\xde\x05/lh' 5
getpid&getppid — 获取进程和父进程

getpid用于返回当前程序(脚本文件)的进程ID, getppid用于返回当前程序(脚本文件)的父进程ID。

获取进程唯一ID(PID)
import os

getpid 返回当前进程的ID
print(os.getpid())  # 10784

getppid 返回父进程的ID
如果父进程已退出,Windows计算机仍将运行返回其id;其他系统将返回"init"进程的id;
print(os.getppid())  # 16468
cpu_count — 获取CPU核心数(逻辑)
import os

print(os.cpu_count())

"""
结果:
8
"""

常用属性

enciron — 操作环境变量
import os

 获取系统的所有环境变量
ev_var = os.environ
print(ev_var)

获取系统指定的环境变量
path_ev_var = os.environ['PATH']
print(path_ev_var)

添加环境变量
os.environ['PATH'] += r':/home/msr'  # Linux使用冒号分隔
os.environ['PATH'] += r';C:\Users\MSR'  # Windows使用分号分隔

事实上,我们可以看到,环境变量实际上是一个特殊的字典,修改环境变量只是操作字典数据。<details><summary>*<font color='gray'>[En]</font>*</summary>*<font color='gray'>In fact, we can see that the environment variable is actually a special dictionary, and modifying the environment variable is just manipulating a dictionary data.</font>*</details>
name & sep & linesep
import os

name 获取系统标识(Linux ->posix   windows -> nt)
print(os.name)  # nt

sep 获取路径分隔符号
print(os.sep)  # \

linesep 获取系统的换行符号
print(repr(os.linesep))  # '\r\n'

文件操作

mknod & remove — 新建&删除文件

windows系统不支持此方法。

import os

os.mknod('test.txt')
os.remove('test.txt')
mkdir & rmdir — 创建&删除文件夹
import os

os.mkdir('test_dir')
os.rmdir('test_dir')
rename — 重命名文件或文件夹

语法:rename(old_path, new_path)

import os

os.rename('test.txt', 'hahaha.txt')
makedirs & removedirs — 迭代创建&删除文件夹
import os

迭代创建文件夹
os.makedirs('a/b/c/d/e')

重复删除文件夹(如果文件夹中有文件,则不会删除该文件夹)<details><summary>*<font color='gray'>[En]</font>*</summary>*<font color='gray'>Iteratively delete a folder (if there are files in the folder, the folder will not be deleted)</font>*</details>
os.removedirs('a/b/c/d/e')

路径模块

import os.path

路径模块也是系统模块的一部分。

[En]

The path module is also part of the system module.

basename — 返回路径中的文件名部分
import os.path

该路径不一定真实存在
file_path = r'..\学习笔记\day1笔记.py'
file_name = os.path.basename(file_path)
print(file_name)  # day1笔记.py
dirname — 返回路径中目录部分
import os.path

file_path = r'..\学习笔记\day1笔记.py'
dir_path = os.path.dirname(file_path)
print(dir_path)  # ..\学习笔记
split — 将目录和文件名拆分成两部分
import os.path

file_path = r'..\学习笔记\day1笔记.py'
tuple_var = os.path.split(file_path)
print(tuple_var)  # ('..\\学习笔记', 'day1笔记.py')
print(type(tuple_var))  # 返回元组:
join — 将多个路径组合在一起
import os.path

path1 = 'abc'
path2 = '123'
path3 = 'main.py'

使用join组合
path = os.path.join(path1, path2, path3)
print(path)  # abc\123\main.py

也可以使用 os.sep
path = path1 + os.sep + path2 + os.sep + path3
print(path)  # abc\123\main.py
splitext — 将文件名分为文件名和后缀名
import os.path

分开文件名
file_name = 'main.py'
res = os.path.splitext(file_name)
print(res)  # ('main', '.py')
print(type(res))  #

分来完整路径
file_path = r'..\学习笔记\day1笔记.py'
res = os.path.splitext(file_path)
print(res)  # ('..\\学习笔记\\day1笔记', '.py')
print(type(res))  #

也可以使用字符串内置方法 split 实现
res = file_path.split('.')
print(res)  # ['', '', '\\学习笔记\\day1笔记', 'py']
print(type(res))  #
getsize — 获取指定文件的大小
import os.path

获取指定文件的大小(单位:byte)
file_size_byte = os.path.getsize('test.txt')
getctime — 获取文件的创建时间

获取文件的创建时间,返回时间戳。(windows有明确的创建时间,linux只有最后一次的修改时间。)

import os.path
import time

获取文件创建时间
stamp_time = os.path.getctime('./test.py')
print(stamp_time)  # 1613989768.3445127

配合 时间模块使用 获取时间
print(time.ctime(stamp_time))  # Mon Feb 22 18:29:28 2021
getmtime — 获取文件的最后一次修改时间
import os.path
import time

获取上次修改文件的时间<details><summary>*<font color='gray'>[En]</font>*</summary>*<font color='gray'>Get the time when the file was last modified</font>*</details>
stamp_time = os.path.getmtime('./test.py')
print(stamp_time)  # 1614037683.1067748

配合 时间模块使用 获取时间
print(time.ctime(stamp_time))  # Tue Feb 23 07:48:03 2021
getatime — 获取文件最后一次访问时间
import os.path
import time

获取文件的上次访问时间<details><summary>*<font color='gray'>[En]</font>*</summary>*<font color='gray'>Get the last access time of the file</font>*</details>
stamp_time = os.path.getatime('./test.py')
print(stamp_time)  # 1635590737.799415

配合 时间模块使用 获取时间
print(time.ctime(stamp_time))  # Sat Oct 30 18:45:37 2021

不检查路径是否为实数。

[En]

Does not check whether the path is real.

import os.path

检查路径类型并返回布尔值:<details><summary>*<font color='gray'>[En]</font>*</summary>*<font color='gray'>Check the path type and return a Boolean value:</font>*</details>
    # 不是对应类型或没有相应文件 : False
    # 是对应类型:True

isdir 检查路径是否是文件夹
res = os.path.isdir('test.txt')

isfile 检查路径是否是文件
res = os.path.isfile('test.txt')

islink 检查路径是否是链接
res = os.path.islink('test.txt')
isabs — 检查路径是否是绝对路径

不检查路径是否真实存在

import os.path

检查windows路径
path = r'E:\小黄片'
res = os.path.isabs(path)
print(res)  # True

windows系统检查Linux路径
path = r'/root/home'
res = os.path.isabs(path)
print(res)  # True
abspath — 相对路径转成绝对路径

首先检查路径是否为相对路径,然后将其转换为绝对路径,反之亦然。

[En]

First check whether a path is a relative path, then convert it to an absolute path, and vice versa.

切换到绝对路径的规则是根据当前工作路径和相对路径中的相对级别,将对应级别的工作路径替换为原始路径中的相对路径。

[En]

The rule for switching to an absolute path is to replace the work path of the corresponding level with the relative path in the original path based on the current work path and the relative level in the relative path.

不检查路径是否为实数。

[En]

Does not check whether the path is real.

import os.path

绝对路径不改变
path = r'E:\学习资料'
new_path = os.path.abspath(path)
print(new_path)  # E:\学习资料

相对路径转成绝对路径
path = r'..\学习资料'
new_path = os.path.abspath(path)
print(new_path)  # E:\0-project\python\学习资料

根据级别自动转换
path = r'..\..\学习资料'
new_path = os.path.abspath(path)
print(new_path)  # E:\0-project\学习资料

如果相对级别太多,则以根目录为准(不上报错误)<details><summary>*<font color='gray'>[En]</font>*</summary>*<font color='gray'>If there are too many relative levels, the root directory will prevail (no error will be reported)</font>*</details>
path = r'..\..\..\..\..\..\..\..\..\..\学习资料'
new_path = os.path.abspath(path)
print(new_path)  # E:\学习资料
exists — 检查路径是否真实存在

检查路径是否存在并返回布尔值。

[En]

Check whether the path exists and return a Boolean value.

import os.path

检查指定路径是否存在
path = r'E:\小黄片'
res = os.path.exists(path)
print(res)  # False

文件复制移动模块(文件操作)

import shutil

用于对文件进行操作。

获取文件信息,获取文件信息,见系统模块。

copyfileobj — 复制文件(内容)

只复制文件的内容,通过文件IO操作,将一个文件的对象复制到另一个文件对象当中,因为需要在文件IO对象中操作,所以不推荐使用。

语法:copyfileobj(fsrc, fdst, length=16*1024)
copyfileobj(被复制文件对象,新文件对象,一次性读取字符数量。)

import shutil

with open('test.txt', 'r', encoding='UTF-8') as fp1 :
   with open('test2.txt', 'w', encoding='UTF-8') as fp2 :
      shutil.copyfileobj(fp1, fp2)
copyfile — 复制文件(内容)

底层调用 copyfileobj,使用方便快捷,所以推荐使用。

语法:copyfile(被复制文件路径, 新文件路径)

import shutil

shutil.copyfile('test.txt', 'test2.txt')
copymode — 复制文件(权限)

仅复制文件的权限,不复制文件的内容(被赋值权限的文件必须存在),语法和 copyfile相同。

import shutil

shutil.copymode('test.txt', 'test.txt')
copystat — 复制文件(除了内容)

复制文件的所有状态信息,包括各种日期和权限。没有内容。

[En]

Copy all the status information of the file, including various dates and permissions. There is no content.

import shutil

shutil.copystat('test.txt', 'test.txt')
copy & copy2 — 复制文件
import shutil

复制文件内容和权限
shutil.copy('test.txt', 'test.txt')

复制整个文件(包括状态、权限、内容)。<details><summary>*<font color='gray'>[En]</font>*</summary>*<font color='gray'>Copy the entire file (including status, permissions, content.)</font>*</details>
shutil.copy2('test.txt', 'test.txt')
copytree — 迭代复制文件夹中的所有
import shutil

shutil.copytree('../学习笔记', '../学习笔记备份')
rmtree — 迭代删除文件夹(即使文件夹中有文件)
import shutil

shutil.rmtree('..\小黄片')
move — 移动文件或文件夹
import shutil

shutil.move('D:\学习资料', 'C:\我的心血')

Original: https://www.cnblogs.com/msr20666/p/16342292.html
Author: 小小垂髫
Title: python常用标准库(os系统模块、shutil文件操作模块)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/499455/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球