哎呀,数据呢?存哪儿了?得给它拽出来啊!说白了,用 Python 怎么读取,不就是想把硬盘里、网上的、甚至别人输入的东西,变成我程序里能用的变量、能处理的字符嘛。这事儿吧,核心工具就是那个叫 open() 的家伙。就像你伸手去拿一个东西,得先“打开”它。

最常用的,读文本文件

这就像你看书,一个字一个字、一行一行地看。在 Python 里,读文本文件,你得用 open() 函数,并且指定模式。最常见的模式是 'r',那个 ‘r’ 就是 read 的缩写。

但记住,一定要用 with open(...) as f: 这个结构!答应我,好吗?别偷懒!因为它帮你处理善后,文件打开了,读完了,它会自动帮你关掉。不然,万一程序崩了,文件可能就一直开着,占资源,甚至被锁死。那感觉,糟透了。

“`python

示范一下,读个文本文件

try:
with open(‘my_precious_data.txt’, ‘r’, encoding=’utf-8′) as f:
# 接下来,你想怎么读就怎么读
content = f.read() # 一口气全读进来
print(“文件内容:\n”, content)
except FileNotFoundError:
print(“哎呀,文件没找到!看看路径对不对?”)
except Exception as e:
print(f”读取文件时出了点岔子:{e}”)

“`

看到没?with open(...) as f:,然后指定文件名 'my_precious_data.txt',模式 'r'。那个 encoding='utf-8' 简直是救星,后面我们单独聊聊这货!as f 就是把打开的文件对象取个名叫 f,方便你操作。

三种主流的“读”姿势

打开文件后,怎么把里面的内容抓出来呢?主要有三种姿势,看你胃口大小和需求急缓:

  1. f.read():一口气吞下去
    想一口气把文件里所有内容都吞下去?用 f.read()。它会把整个文件内容作为一个巨大的字符串返回给你。

    python
    with open('大文件警告.log', 'r', encoding='utf-8') as f:
    all_text = f.read()
    # 小心!文件太大,内存会哭给你看!
    # print(all_text)

    注意啊,要是文件特大,你内存可能就爆了。像个贪吃鬼,啥都往肚子里塞,但肚子(内存)是有限的。不到万不得已(确定文件小或者内存富裕),别这么干。不过读个配置文件、几k的小日志,这个方法最省事。

  2. f.readline():一口一口品尝
    或者你想一行一行地品味?就像喝茶,一口一口来。f.readline() 就是干这活儿的。每次调用,它就返回文件的一行(包括末尾的换行符 \n),直到文件末尾,返回一个空字符串 ''

    python
    print("一行一行读:")
    with open('log.txt', 'r', encoding='utf-8') as f:
    line = f.readline()
    while line:
    print(f"读到一行: {line.strip()}") # strip() 去掉行尾的换行符
    line = f.readline()

    这个姿势处理日志文件、CSV 文件等,一行一个事件或一条记录,绝配!内存占用低,特别适合处理大文件。

  3. f.readlines():把所有行打包成列表
    想把所有行都变成一个列表?每行作为列表里的一项。f.readlines()

    python
    print("\n把所有行放列表里:")
    with open('config.ini', 'r', encoding='utf-8') as f:
    lines_list = f.readlines()
    # print(lines_list)
    for i, line in enumerate(lines_list):
    print(f"第 {i+1} 行: {line.strip()}")

    这个也方便,特别是你需要对所有行进行迭代处理或者排序的时候。但同样,文件太大,这个列表也可能撑爆内存。它其实就是用 readline() 循环读到文件尾,然后把读到的每一行扔进一个列表里。

更 Pythonic 的读行方式:直接迭代文件对象

其实啊,读行还有一个更酷、更简洁的方式,就是直接遍历文件对象 f 本身!

python
print("\n最优雅的读行方式:")
with open('another_log.txt', 'r', encoding='utf-8') as f:
for line in f:
print(f"又读到一行: {line.strip()}")

这个 for line in f: 的方式,在后台其实也是一行一行地读,效率高,代码简洁,是处理大文件时读行的首选,强烈推荐!

那个让人抓狂的“编码”问题 (Encoding)

前面提到的 encoding='utf-8',这事儿太重要了!读文本文件,如果文件保存时的编码和你的程序打开时指定的编码不一致,恭喜你,一堆乱码甚至 UnicodeDecodeError 正在向你招手。那堆看不懂的字符蹦出来的时候,是不是想砸电脑?

UnicodeDecodeError,多么“亲切”的错误信息啊!它告诉你,“哥们,我用你指定的编码(比如默认的 ASCII,或者你指定的 UTF-8)去理解文件里的字节流,发现它们根本不符合这个编码的规范!”

为了避免这个,务必open() 里加上 encoding='utf-8'。现在基本上全世界的网页、新创建的文本文件都倾向于用 UTF-8 了,它能表示几乎所有语言的字符,统一战线,方便你我。

当然,遇到那种古老的、从 Windows XP 时代传下来的 txt 文件,它可能用的是 GBK、GB2312 甚至 Latin-1。那时候,你就得根据文件的实际编码来指定了,比如 encoding='gbk'。怎么知道文件的编码?有时候是玄学,得靠经验、靠文本编辑器(比如 VS Code、Notepad++ 都能识别)或者专门的编码检测库(比如 chardet)来猜。猜对了皆大欢喜,猜错了?嘿嘿,乱码继续陪你玩。

读非文本文件:二进制模式 ('rb')

好了,不是所有文件都是文本。图片 (.jpg, .png)、音频 (.mp3)、视频 (.mp4)、压缩包 (.zip, .gz)、还有 Python 里用 pickle 序列化保存的对象… 这些都是二进制文件。它们不是由人类可读的字符组成的,而是一堆字节 (bytes)。

读这些文件,模式就得换成 'rb'。那个 ‘b’ 就是 binary 的意思。

“`python

读个图片文件试试

try:
with open(‘my_image.jpg’, ‘rb’) as f:
binary_data = f.read() # 读到的是 bytes 类型的数据
print(f”读取了 {len(binary_data)} 个字节的图片数据。类型是: {type(binary_data)}”)
# print(binary_data[:20]) # 打印前20个字节看看
# 你不能直接 print 二进制数据,它不是字符串!
# 通常你会用特定的库来处理这些 bytes,比如 PIL 处理图片,pickle 加载对象
except FileNotFoundError:
print(“图片文件没找到!”)
``
‘rb’模式下,f.read()返回的是bytes对象,而不是strf.readline()f.readlines()也能用,但它们返回的是以换行符(在二进制里就是特定的字节序列)分割的bytes` 行。处理二进制数据,感觉就像在处理最原始的积木块,没啥字符格式可言,就是一堆数字(0-255)。处理图片库、网络通信、文件复制啥的,这个模式少不了。

别忘了错误处理 (Error Handling)

我们前面已经零星地提到了,但值得单独强调:读取文件这事儿,外部因素太多了!文件可能不存在、路径错了、你没权限读、文件被别人占用了… 任何一步都可能出错。

所以啊,用 try...except 把你的文件读取代码包起来,是个好习惯,不,是个必须养成的习惯!

“`python
file_path = ‘maybe_exists.txt’
try:
with open(file_path, ‘r’, encoding=’utf-8′) as f:
content = f.read()
print(f”成功读取文件 {file_path}:\n{content}”)
except FileNotFoundError:
print(f”惨了!要读的文件 ‘{file_path}’ 不存在啊!”)
except PermissionError:
print(f”没权限!'{file_path}’ 文件不让我读!”)
except UnicodeDecodeError:
print(f”编码问题!文件 ‘{file_path}’ 不是 UTF-8 编码,试试别的编码?”)
except Exception as e:
print(f”读取文件 ‘{file_path}’ 时发生未知错误: {e}”)

“`
这样,就算文件出问题,你的程序也不会直接崩掉,而是会给用户一个友好的提示,或者至少不会卡死在那里。

还有别的方式“读”吗?

除了从文件系统读,Python 还能从别的地方“读”数据啊!

  • 标准输入 (Standard Input): 就是用户在命令行里敲的东西。input() 函数大家都熟,它就是从标准输入里读一行字符串。想读更复杂的?sys.stdin,不过那个用得可能少点,除非你在写特别底层的命令行工具。

  • 网络连接 (Network Connections): 通过 socket 或者各种库(如 requests),你可以从网络上“读取”数据流。这跟读文件有点像,也是一串字节流,但源头是网络。

  • 内存中的字符串 (In-memory Strings): 你甚至可以把一个字符串当成文件来读!io.StringIOio.BytesIO 这两个类就能干这事儿。当你有些文本或字节数据已经在内存里了,但你又想用文件对象那样的方法(比如 .read(), .readline())去处理它,它们就派上用场了。

“`python

把字符串当文件读

import io
string_data = “第一行文本\n第二行。\n第三行就这么结束了。”
string_io = io.StringIO(string_data)

print(“\n从内存字符串读:”)
print(string_io.readline().strip())
print(string_io.read()) # 从当前位置读到尾
“`

你看,Python 怎么读取 这事儿,看着简单一个 open(),里面弯弯绕绕还不少呢。模式、编码、读取方式、异常处理、还有那个救命的 with 语句。每一个环节都可能藏着 bug,尤其是编码,绝对是新手的老大难。但掌握了这些,你就能轻松地把外部世界的数据‘吸’进你的程序里,让它们活起来。就像给你的程序装上了眼睛和耳朵,能感知外面的信息了。是不是挺酷的?多练练,找几个不同格式的文件试试,感觉就来了。别怕踩坑,踩着踩着,你就知道哪儿有坑,怎么绕过去了。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。