python 模块 输入与输出
模块(Modules)
1. 模块的定义与导入
定义
- 模块是一个包含Python定义和语句的文件。模块可以定义函数、类和变量,还可以包含可执行的代码。
- 通过模块,可以组织和重用代码,促进代码的模块化和维护性。
导入模块
- 使用
import
语句导入模块。 - 语法:
import module_name
- 例子:
import math print(math.sqrt(16)) # 输出: 4.0
从模块中导入特定部分
- 使用
from ... import ...
语句。 - 语法:
from module_name import function_name
- 例子:
from math import sqrt print(sqrt(25)) # 输出: 5.0
导入所有内容
- 使用
from module_name import *
导入模块的所有公共属性和方法。 - 例子:
from math import * print(pi) # 输出: 3.141592653589793 print(sin(0)) # 输出: 0.0
- 注意:不推荐使用
import *
,因为它可能导致命名冲突,降低代码可读性。
使用别名
- 使用
as
关键字为模块或导入的部分指定别名。 - 例子:
import math as m print(m.sqrt(9)) # 输出: 3.0from math import sqrt as square_root print(square_root(16)) # 输出: 4.0
2. 模块搜索路径
搜索顺序
当导入模块时,Python解释器会按照以下顺序搜索模块:
- 当前目录:首先在当前脚本所在的目录查找模块。
- 环境变量
PYTHONPATH
:如果设置了PYTHONPATH
,则在该路径下搜索。 - 标准库目录:搜索Python安装目录下的标准库模块。
- 第三方库目录:搜索安装的第三方库模块。
查看搜索路径
- 使用
sys
模块的sys.path
属性查看当前的模块搜索路径。 - 例子:
import sys print(sys.path)
修改搜索路径
- 可以在运行时通过修改
sys.path
来添加新的搜索路径。 - 例子:
import sys sys.path.append('/path/to/your/module')
3. 标准模块
标准库概述
- Python提供了丰富的标准库模块,涵盖了文件操作、系统调用、网络编程、数据处理等多个领域。
- 常用标准模块包括
sys
,os
,math
,datetime
,json
,re
等。
例子:使用 datetime
模块
import datetimenow = datetime.datetime.now()
print(now) # 输出当前日期和时间
4. 创建模块
创建一个简单模块
- 创建一个Python文件,例如
mymodule.py
,并定义一些函数和变量。# mymodule.pydef greet(name):return f"Hello, {name}!"pi = 3.141592653589793
- 在另一个脚本中导入并使用该模块。
import mymoduleprint(mymodule.greet("Alice")) # 输出: Hello, Alice! print(mymodule.pi) # 输出: 3.141592653589793
模块的命名空间
- 每个模块都有自己的命名空间,模块内部的变量不会影响其他模块,反之亦然。
- 可以使用
dir()
函数查看模块的属性。import mymodule print(dir(mymodule))
5. 包(Packages)
定义
- 包是一种组织模块的方式,使用文件夹和
__init__.py
文件实现。 - 包可以包含子包和模块,形成层级结构。
创建包
-
创建一个文件夹,例如
mypackage
,并在其中添加一个__init__.py
文件(可以为空)。 -
在
mypackage
文件夹中添加模块文件,例如module1.py
和module2.py
。mypackage/__init__.pymodule1.pymodule2.py
-
导入包中的模块:
from mypackage import module1 from mypackage.module2 import some_function
相对导入
- 在包内部,可以使用相对导入来引用同一包中的其他模块。
- 使用
.
表示当前包,..
表示上级包。# 在 mypackage/module1.py 中 from . import module2 from .module2 import some_function
6. 模块的命名空间
全局变量与局部变量
- 模块的全局变量在整个模块中可见。
- 在函数或类内部定义的变量是局部变量,仅在其作用范围内可见。
__name__
变量
-
每个模块都有一个特殊变量
__name__
,表示模块的名称。 -
当模块被直接运行时,
__name__
的值为'__main__'
。 -
当模块被导入时,
__name__
的值为模块的实际名称。# mymodule.py if __name__ == "__main__":print("模块被直接运行") else:print("模块被导入")
7. from-import 语句
基本用法
- 从模块中导入特定的属性或方法,避免使用模块前缀。
from math import sqrt, pi print(sqrt(16)) # 输出: 4.0 print(pi) # 输出: 3.141592653589793
导入所有内容
- 使用
from module import *
导入模块的所有公共属性和方法。from math import * print(sin(0)) # 输出: 0.0
- 注意:这种方式可能导致命名冲突,需谨慎使用。
为导入的属性指定别名
- 使用
as
关键字为导入的属性指定别名。from math import sqrt as square_root print(square_root(25)) # 输出: 5.0
8. 动态导入模块
使用 __import__
函数
- 可以在运行时动态导入模块,适用于需要根据变量导入不同模块的情况。
module_name = "math" math_module = __import__(module_name) print(math_module.sqrt(9)) # 输出: 3.0
使用 importlib
模块
- 更现代和灵活的动态导入方式。
import importlibmodule_name = "math" math_module = importlib.import_module(module_name) print(math_module.pi) # 输出: 3.141592653589793
9. 模块的生命周期
导入模块时的执行过程
- 当模块被首次导入时,Python会执行模块中的所有顶层代码,并将模块对象存储在
sys.modules
中。 - 后续导入相同模块时,不会重新执行模块代码,而是直接从
sys.modules
中获取模块对象。
模块的缓存
-
sys.modules
是一个字典,保存了所有已导入的模块。它可以用于检查模块是否已被导入,或动态修改模块。import sys import mathprint('math' in sys.modules) # 输出: True
10. 编写可重用的代码
模块化编程的优势
- 代码重用:将常用功能封装在模块中,便于多处使用。
- 命名空间隔离:避免不同模块之间的命名冲突。
- 可维护性:模块化代码更易于理解和维护。
示例:创建一个工具模块
# utils.pydef add(a, b):return a + bdef subtract(a, b):return a - b
# main.pyimport utilsprint(utils.add(5, 3)) # 输出: 8
print(utils.subtract(10, 4)) # 输出: 6
11. 内建模块(Built-in Modules)
概述
- Python提供了许多内建模块,随解释器一起分发,无需额外安装即可使用。
- 常用内建模块包括
sys
,os
,math
,datetime
,json
,re
,random
等。
示例:使用 random
模块
import randomprint(random.randint(1, 10)) # 输出: 1到10之间的随机整数
print(random.choice(['apple', 'banana', 'cherry'])) # 随机选择一个水果
12. 模块的高级特性
包的相对导入
- 在包内部,可以使用相对导入来引用同一包中的其他模块。
- 示例结构:
mypackage/__init__.pymodule1.pysubpackage/__init__.pymodule2.py
- 在
module2.py
中导入module1
:from .. import module1
动态修改模块
- 可以在运行时添加、删除或修改模块的属性。
import math math.new_attribute = "新的属性" print(math.new_attribute) # 输出: 新的属性
模块的生命周期管理
- 使用
importlib.reload()
可以重新加载模块,适用于开发过程中需要更新模块内容的场景。import importlib import mymoduleimportlib.reload(mymodule)
13. __main__
模块
定义
- 当模块被直接运行时,
__name__
变量被设置为'__main__'
。 - 这使得模块可以区分是被导入还是被直接运行,从而执行不同的代码逻辑。
示例
# mymodule.pydef main():print("模块被直接运行")if __name__ == "__main__":main()
# 直接运行模块
$ python mymodule.py
输出: 模块被直接运行# 导入模块
>>> import mymodule
# 不会输出任何内容
14. 小结
模块是Python中组织和重用代码的基本单元。通过模块化编程,可以提高代码的可维护性、可读性和复用性。理解模块的导入机制、搜索路径、命名空间以及包的结构,是高效编写Python程序的关键。
15. 实践建议
- 合理组织代码:将相关功能封装在模块和包中,避免模块过于庞大。
- 使用有意义的命名:为模块和包选择描述性强的名称,便于理解和使用。
- 遵循PEP 8:遵循Python的编码规范(PEP 8),保持代码一致性和可读性。
- 避免循环依赖:模块之间尽量减少相互依赖,避免复杂的循环导入关系。
- 利用标准库:在编写新模块前,先查找是否已有标准库模块或第三方库能够满足需求。
输入与输出(Input and Output)
更复杂的输出格式
在 Python 中,除了基本的 print()
函数外,还有多种方法可以实现更复杂和灵活的输出格式,包括格式化字符串字面值(f-strings)、str.format()
方法、手动格式化字符串以及旧式的字符串格式化方法。
格式化字符串字面值(f-strings)
定义与特性:
- 从 Python 3.6 开始引入的字符串格式化方法,使用前缀
f
或F
。 - 允许在字符串中嵌入表达式,表达式放在花括号
{}
内。
示例:
name = "Alice"
age = 30
print(f"姓名:{name},年龄:{age}")
# 输出: 姓名:Alice,年龄:30# 带表达式
pi = 3.14159
print(f"圆周率约为 {pi:.2f}")
# 输出: 圆周率约为 3.14
优势:
- 语法简洁,易读性强。
- 支持表达式计算,可以直接在字符串中进行计算和调用函数。
字符串 format()
方法
定义与用法:
- 使用花括号
{}
作为占位符,通过str.format()
方法插入变量。 - 支持位置参数和关键字参数。
示例:
name = "Bob"
age = 25
print("姓名:{},年龄:{}".format(name, age))
# 输出: 姓名:Bob,年龄:25# 使用关键字参数
print("姓名:{name},年龄:{age}".format(name="Charlie", age=28))
# 输出: 姓名:Charlie,年龄:28# 嵌套字段
data = {'name': 'Diana', 'age': 22}
print("姓名:{name},年龄:{age}".format(**data))
# 输出: 姓名:Diana,年龄:22
格式说明符:
- 可以在花括号内添加格式说明符,如指定宽度、对齐方式、小数位数等。
pi = 3.14159
print("圆周率约为 {:.2f}".format(pi))
# 输出: 圆周率约为 3.14
手动格式化字符串
定义与用法:
- 通过字符串的拼接或转换,将变量手动插入到字符串中。
- 使用
+
运算符或,
分隔符。
示例:
name = "Eve"
age = 35
print("姓名:" + name + ",年龄:" + str(age))
# 输出: 姓名:Eve,年龄:35print("姓名:", name, ",年龄:", age, sep="")
# 输出: 姓名:Eve,年龄:35
注意事项:
- 需要手动转换非字符串类型为字符串。
- 代码可能较为冗长,可读性较低。
旧式字符串格式化方法
定义与用法:
- 使用
%
运算符进行字符串格式化。 - 类似于 C 语言中的
printf
风格。
示例:
name = "Frank"
age = 40
print("姓名:%s,年龄:%d" % (name, age))
# 输出: 姓名:Frank,年龄:40pi = 3.14159
print("圆周率约为 %.2f" % pi)
# 输出: 圆周率约为 3.14
注意事项:
- 虽然仍然被支持,但不推荐在新代码中使用,因为
str.format()
和 f-strings 提供了更强大的功能和更好的可读性。
读写文件
Python 提供了多种方法来读取和写入文件,包括文本文件和二进制文件的操作,以及使用 JSON 保存结构化数据。
文件对象的方法
打开文件:
- 使用
open()
函数打开文件,返回文件对象。 - 常用模式包括读取
'r'
、写入'w'
、追加'a'
,以及二进制模式'rb'
,'wb'
等。
示例:
# 以读取模式打开文件
f = open('example.txt', 'r', encoding='utf-8')# 以写入模式打开文件
f = open('example.txt', 'w', encoding='utf-8')
常用方法:
-
read(size=-1)
:读取指定大小的内容,默认读取全部内容。with open('example.txt', 'r', encoding='utf-8') as f:content = f.read()print(content)
-
readline()
:读取文件的一行内容。with open('example.txt', 'r', encoding='utf-8') as f:line = f.readline()while line:print(line, end='')line = f.readline()
-
readlines()
:读取文件的所有行,返回一个列表。with open('example.txt', 'r', encoding='utf-8') as f:lines = f.readlines()for line in lines:print(line, end='')
-
write(string)
:将字符串写入文件。with open('example.txt', 'w', encoding='utf-8') as f:f.write('Hello, World!\n')f.write('这是一个示例文件。\n')
-
writelines(lines)
:将一个字符串列表写入文件,不自动添加换行符。lines = ['第一行\n', '第二行\n', '第三行\n'] with open('example.txt', 'w', encoding='utf-8') as f:f.writelines(lines)
使用 with
语句管理文件:
- 使用
with
语句可以自动管理文件资源,确保文件在使用完毕后正确关闭,即使发生异常也能保证关闭文件。 - 示例:
with open('example.txt', 'r', encoding='utf-8') as f:content = f.read()print(content)
文件模式:
'r'
:只读模式,文件指针放在文件开头。'rb'
:二进制读取模式。'w'
:写入模式,会覆盖已有文件。'wb'
:二进制写入模式。'a'
:追加模式,文件指针放在文件末尾。'ab'
:二进制追加模式。'r+'
:读写模式,文件指针放在开头。'w+'
:写读模式,会覆盖文件。'a+'
:追加读写模式。
文件指针操作:
tell()
:返回文件指针的当前位置(以字节为单位)。with open('example.txt', 'r', encoding='utf-8') as f:f.read(10)position = f.tell()print(f"当前文件指针位置:{position}")
seek(offset, whence)
:移动文件指针到指定位置。offset
:偏移量。whence
:参考点,0
表示文件开头,1
表示当前位置,2
表示文件末尾。
with open('example.txt', 'r', encoding='utf-8') as f:f.seek(5) # 移动到第6个字节data = f.read(10)print(data)
使用 JSON 保存结构化数据
定义与用途:
- JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。
- 适用于保存和传输结构化数据,如配置文件、数据存储等。
Python 中的 JSON 模块:
- Python 提供了内置的
json
模块,用于处理 JSON 数据的编码和解码。
常用函数:
-
json.dump(obj, fp, ...)
:将 Python 对象编码为 JSON 格式,并写入文件对象fp
。import jsondata = {'name': 'Alice','age': 30,'city': 'Beijing','interests': ['reading', 'traveling'] }with open('data.json', 'w', encoding='utf-8') as f:json.dump(data, f, ensure_ascii=False, indent=4)
-
json.load(fp, ...)
:从文件对象fp
中读取 JSON 数据,并解码为 Python 对象。import jsonwith open('data.json', 'r', encoding='utf-8') as f:data = json.load(f)print(data) # 输出: {'name': 'Alice', 'age': 30, 'city': 'Beijing', 'interests': ['reading', 'traveling']}
-
json.dumps(obj, ...)
:将 Python 对象编码为 JSON 字符串。import jsondata = {'name': 'Bob', 'age': 25} json_str = json.dumps(data) print(json_str) # 输出: {"name": "Bob", "age": 25}
-
json.loads(s, ...)
:将 JSON 字符串解码为 Python 对象。import jsonjson_str = '{"name": "Charlie", "age": 28}' data = json.loads(json_str) print(data) # 输出: {'name': 'Charlie', 'age': 28}
参数说明:
ensure_ascii
:默认为True
,确保输出的所有字符都是 ASCII 字符。设为False
可输出非 ASCII 字符。indent
:设置缩进级别,使输出的 JSON 更加美观和易读。
示例:保存和读取复杂数据结构:
import json# 复杂数据结构
data = {'employees': [{'name': 'Alice', 'age': 30, 'department': 'HR'},{'name': 'Bob', 'age': 25, 'department': 'IT'},{'name': 'Charlie', 'age': 28, 'department': 'Finance'}],'company': 'TechCorp','location': 'New York'
}# 写入 JSON 文件
with open('company.json', 'w', encoding='utf-8') as f:json.dump(data, f, ensure_ascii=False, indent=4)# 读取 JSON 文件
with open('company.json', 'r', encoding='utf-8') as f:loaded_data = json.load(f)print(loaded_data)
输出:
{"employees": [{"name": "Alice","age": 30,"department": "HR"},{"name": "Bob","age": 25,"department": "IT"},{"name": "Charlie","age": 28,"department": "Finance"}],"company": "TechCorp","location": "New York"
}
注意事项:
- JSON 支持的数据类型有限,主要包括对象(字典)、数组(列表)、字符串、数字、布尔值和
null
。不支持自定义对象或复杂数据类型,需先转换为可序列化的格式。 - 使用
json
模块时,确保数据结构中所有键和值都是 JSON 支持的类型。
读写二进制文件
除了文本文件,Python 还支持二进制文件的读写操作,适用于处理图片、音频、视频等非文本数据。
读取二进制文件:
with open('image.png', 'rb') as f:data = f.read()# 处理二进制数据
写入二进制文件:
with open('copy_image.png', 'wb') as f:f.write(data)
注意事项:
- 在二进制模式下,读写的是字节对象(
bytes
),而不是字符串。 - 处理二进制数据时,需要注意编码和解码问题,确保数据的正确性。
文件对象的方法
常用方法概览:
read(size=-1)
:读取指定大小的内容,默认读取全部内容。readline(size=-1)
:读取一行内容。readlines(hint=-1)
:读取所有行,返回列表。write(string)
:写入字符串。writelines(lines)
:写入字符串列表。seek(offset, whence=0)
:移动文件指针。tell()
:返回文件指针当前位置。flush()
:刷新缓冲区,将数据写入文件。close()
:关闭文件。
示例:
# 读取文件内容
with open('example.txt', 'r', encoding='utf-8') as f:content = f.read()print(content)# 写入文件内容
with open('example.txt', 'w', encoding='utf-8') as f:f.write('Hello, Python!\n')f.write('这是第二行内容。\n')
使用 with
语句:
- 自动管理文件资源,确保文件在使用完毕后关闭。
with open('example.txt', 'r', encoding='utf-8') as f:for line in f:print(line, end='')
总结
Python 的输入与输出操作功能强大且灵活,涵盖了从简单的打印信息到复杂的文件读写操作、数据格式化以及结构化数据处理。通过掌握以下关键点,可以有效地处理各种 I/O 需求:
-
文件操作:
- 使用
open()
函数以不同模式打开文件。 - 通过
read()
,readline()
,readlines()
,write()
,writelines()
等方法进行文件内容的读取和写入。 - 使用
with
语句自动管理文件资源,确保文件正确关闭。 - 处理文件指针的移动和当前位置的获取。
- 使用
-
输出格式化:
- 使用
print()
函数进行基本输出。 - 利用 f-strings、
str.format()
方法实现复杂和灵活的字符串格式化。 - 了解手动格式化和旧式格式化方法,但推荐使用 f-strings 或
str.format()
。
- 使用
-
处理结构化数据:
- 使用
json
模块读取和写入 JSON 数据,适用于配置文件和数据交换。 - 理解 JSON 的数据类型限制,确保数据可序列化。
- 使用
-
读写二进制文件:
- 了解如何以二进制模式打开和处理文件,适用于非文本数据。
理解并灵活运用这些输入与输出的方法和技巧,能够显著提升 Python 程序的功能性和用户体验。