当前位置: 首页 > news >正文

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解释器会按照以下顺序搜索模块:

  1. 当前目录:首先在当前脚本所在的目录查找模块。
  2. 环境变量 PYTHONPATH:如果设置了 PYTHONPATH,则在该路径下搜索。
  3. 标准库目录:搜索Python安装目录下的标准库模块。
  4. 第三方库目录:搜索安装的第三方库模块。
查看搜索路径
  • 使用 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.pymodule2.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 开始引入的字符串格式化方法,使用前缀 fF
  • 允许在字符串中嵌入表达式,表达式放在花括号 {} 内。

示例

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 程序的功能性和用户体验。


http://www.mrgr.cn/news/54665.html

相关文章:

  • C/C++ 每日一练:单链表的反转
  • 我在办公室的录屏体验:笔记本电脑上的五大神器大比拼
  • linux系统中chmod用法详解
  • golang的协程
  • OpenCV高级图形用户界面(21)暂停程序执行并等待用户按键输入函数waitKey()的使用
  • git解决推送时出现 this exceeds GitHub‘s file size limit of 100.00 MB
  • 探究互联网数字化商品管理变革:从数据化到精准运营的路径转型
  • Leaflet地图中实现绘图(点、线、多边形、圆等)功能
  • 美学心得(第二百六十八集) 罗国正
  • 机器学习【工业高精度计算及其应用】
  • C++头文件大全及解释(补丁)
  • 一 、揭秘操作系统架构:从整体式到微内核的技术演变
  • <Project-11 Calculator> 计算器 0.3 年龄计算器 age Calculator HTML JS
  • 可达性分析法
  • 力扣71~75题
  • docker容器操作
  • 最近很火的ITIL证书是什么证书?
  • 软硬连接,Linux下的动静态库
  • Nat Comput Sci | 分而治之!基于子任务分解的单细胞扰动人工智能模型 STAMP
  • 洛谷 P1038 [NOIP2003 提高组] 神经网络(拓扑排序)
  • Redis之持久化机制和实现原理
  • C/C++程序员为什么要了解汇编?汇编语言的好处与学习路径详解
  • Python进阶语法
  • Vue request请求拦截 全局拦截Promise后 api请求捕获异常catch
  • day3:管道,解压缩,vim
  • 写一段代码判断素数的函数,从主函数中输出一个整数,判断它是否为素数。