Python 文件&目录操作

1 | 文件 I/O

普通文件,有时也称为平面文件(flat file),是最简单的持久化形式。将文件内容读入内存,再将内存中的内容写入文件,标准库os提供了许多系统函数,Python文件操作像 Unix

1-1 | 基本操作

  • open(filename, mode)

    打开文件,目标文件不存在,则创建文件

    mode 的第一个字符指定了操作

    • r 表示读取。
    • w 表示写入。如果文件不存在,则创建文件;如果同名文件存在,就覆盖该文件。
    • x 表示仅在指定文件存在时写入。
    • a 表示如果文件存在,则在文件末尾追加写入

    mode 的第二个字符指定了文件类型

    • t(或忽略)表示文本文件
    • b 表示二进制文件
    new_file = open('new_text.txt','wt')
    

    处理文件后,必须new_file.close() 关闭文件,确保写入操作完成并释放内存

  • print(text, file=file_obj)

    可用于向文件中写入文本,传入一个 open() 打开的文件对象,由于参数 text 会转成字符串,因此无法写入二进制模式的文件⚠️

    print('A new line', file=new_file)
    
  • write(fd, str, /) 写入文件

    wb 模式打开文件,则写入二进制数据

    >>> poem = "This is a fake poem...."
    >>> f = open('file_name.txt', 'wb')
    >>> f.write(poem)  
    23 # 返回写入文本的长度
    >>> f.close()
    

    💡 若源字符串较长,则分段写入

    with open('test.txt', 'wt') as f:
        offset, chunk = 0, 100
        while offset < len(poem):
            f.write(poem[offset:offset+chunk])
            offset = offset + chunk
    
  • read() readline() readlines() 读取文本

    💡 read()一次性读取所有内容,并消耗等量的内存,可以通过 read(n) 读取指定数量的字符

    file.readline() # 读取一行,返回字符串
    file.readlines() # 读取所有行,返回 list[str]
    
  • tell() seek() 读取位置

    无论读写,Python 会追踪文件位置,

    • tell()查看当前距文件起始的字节偏移
    • seek(offset, from_what)可跳转到指定的文件字节偏移位置

    💡二者主要用于二进制文件。也可用于文本文件,但除非该文件采用的是 ASCII 编码(一个字符对应一字节),否则计算偏移值很麻烦。具体取决于文本编码,UTF-8 对每个字符使用的字节数不尽相同

  • 自动关闭 with

    Python 的上下文管理器context manager会清理一些资源,完成操作后应关闭文件

    with open('filename','wt') as file
    

1-2 | 文件打开后没有 close 会怎样❓

如果在函数内打开了文件,但没有关闭,那么当函数结束时,该文件会被自动关闭。如果是在长时间运行的函数或主程序部分打开的文件,则应该主动关闭,强制完成未执行的写操作

1-3 | 内存映射

读写文件的另一种方法是使用 mmap 模块进行内存映射。使文件内容类似内存中的 bytearray

1-4 | 显示声明编码

Windows 系统会出现的问题,open() 时务必指明字符集

>>> open('cafe.txt', 'w', encoding='utf_8').write('café')
4
>>> open('cafe.txt').read()
'caf茅'
>>> open('cafe.txt', encoding='utf-8').read()
'café'

Python 处理文件时如何获取默认字符集?

import locale
>>> locale.getpreferredencoding()
'cp936'
>>> sys.getdefaultencoding()
'utf-8'

2 | 文件操作

2-1 | copy()

shutil.move() 函数会先复制文件,然后删除源文件

import shutil
>>> shutil.copy('new_text.txt','new.txt') # 复制文件
'new.txt'
>>> shutil.move('...','...') # 相当于剪切

2-2 | remove()

os.remove('c.txt') #删除文件

2-3 | exists()

检查文件或目录是否存在,传入相对或绝对路径

import os
>>> os.path.exists('..') # 表示上层目录
True
>>> os.path.exists('filename')  # check a file
True

2-4 | isfile() isdir() isabs()

检查一个名称是文件、目录还是绝对路径

>>> name = 'new_text.txt'
>>> os.path.isfile(name)
True
# 单点号`.`表示当前目录,双点号`..`表示父目录
>>> os.path.isdir('.')
True
# 仅检查,非真实路径亦可
>>> os.path.isabs('D:\Alita')
True

2-5 | rename()

剪切文件

os.rename('new.txt','n.txt')
os.rename('redis1.md', 'static/redis1.md')  # also can use to move file

2-6 | link() symlink() islink()

在Unix中,文件只存在一个位置,但可有多个名称,即链接

对于低层的硬链接而言,很难找出特定文件的所有名称

符号链接则是一种以独立文件的形式存储文件新名称的方法,可以同时获得原始名称和新名称

>>> os.link('n.txt','b.txt') # 创建一个硬链接
>>> os.path.isfile('b.txt')
True
>>> os.path.islink('b.txt')
False
>>> os.symlink('n.txt','a.txt')  # 创建符号链接
>>> os.path.islink('a.txt')
True

2-7 | chmod()

该方法可修改文件权限,入参是文件名和一个八进制的值

>>> os.chmod('n.txt', 0o400)

# stat 模块中有常量,可避免八进制字符
>>> import stat
>>> os.chmod('n.txt', stat.S_IRUSR)

2-8 | chown()

可指定用户ID和组ID来修改文件所有者或所有组, 类 Unix 系统特有功能

>>> uid, gid = 1, 2
>>> os.chown('n', uid, gid)

3 | 目录操作

3-1 | 基础操作

os.getcwd()      # 获取当前目录
os.mkdir('folder')      # 创建目录
os.rmdir('folder')      # 删除目录
os.listdir('Dance')     # 列出目录内容
['settings.py', 'urls.py', 'wsgi.py', '__init__.py', '__pycache__']
os.chdir('foldername')  # 切换目录

3-2 | 列出匹配文件

glob() 可根据 Unix shell 的通配符规则列出匹配的文件名或目录名。规则如下:

  • \* 匹配任意多个字符(对应的正则表达式为 .*);
  • ? 匹配单个字符;
  • [abc] 匹配 abc
  • [!abc] 匹配除 abc 之外的任意字符。
import glob
>>> glob.glob('a*') # 查找以a开头的文件或路径
['admin.py', 'apps.py']

>>> glob.glob('????????') # 查找文件或目录名为8个字符的
['admin.py', 'tests.py', 'views.py']

>>> glob.glob('a??????y') # 查找首末结尾为a和y 且中间有6个字符的文件或路径
['admin.py']

>>> glob.glob('[af]*y') #查找所有以af开头,以y为结尾的文件和目录
['admin.py', 'apps.py', 'fibo.py']

4 | 路径名

Unix、Mac、Web URL 使用斜线 / 作为路径分隔符,Windows 则使用反斜线 \

反斜线在 Python 中用作转义字符,所以要么使用连续两个反斜线 \\,要么使用 Python 的原始字符串 r""

4-1 | abspath()

相对路径 —扩展—>绝对路径

>>> os.path.abspath('n.txt')
'D:\\n.txt'

4-2 | realpath()

获取绝对路径,符号链接所指向的文件

>>> os.path.realpath('a.txt')
'D:\\a.txt'

4-3 | os.path.join()

以当前操作系统的路径分隔符拼接路径,直接拼接字符串导致写死的分隔符在不同系统间不通用

p = os.path.join("dir1", "filename")
>>> p  # linux
'dir1/filename'
>>> p  # win
'dir1\\filename'

4-4 | pathlib

🆕 Python 3.4 新增,用于代替 os.path 模块

区别:将路径视为对象 ,不再是普通的字符串,通过 / 拼接

from pathlib import Path
new_path = Path('aaa') / Path('words.txt')

>>> new_path
WindowsPath('aaa/words.txt')

💡获取路径信息更加方便

>>> new_path.name
'words.txt'
>>> new_path.suffix
'.txt'
>>> new_path.stem
'words'
>>> new_path.parent
WindowsPath('aaa')

5 | BytesIO、StringIO

需求:要处理内存中的数据,但调用的函数只接受文件(或者是相反的情况)?

io.BytesIOio.StringIO,前者用于二进制数据bytes,后者用于文本数据str

使用场景:数据格式转换

from io import BytesIO
from PIL import Image

def data_to_img(data):
    """Return PIL Image object, with data from in-memory <data>"""
    fp = BytesIO(data)
    return Image.open(fp)     # 读取内存

def img_to_data(img, fmt=None):
    """Return image data from PIL Image <img>, in <fmt> format"""
    fp = BytesIO()
    if not fmt:
        fmt = img.format     # 保存原始格式
    img.save(fp, fmt)        # 写入内存
    return fp.getvalue()

💡getvalue() 可以返回 BytesIO 对象的所有字节

END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值