目录
模块的概念和使用
模块的概念
模块的导入
导入指定的函数或变量
给模块起别名
模块的重载
使用reload()函数
修改模块后重新加载
注意事项
包的概念和使用
包的概念
包的使用
包的导入
包的相对导入
包的 __init__.py 文件
包的使用注意事项
Python的模块是一个包含了相关函数、类、变量和常量等的代码块,模块通常保存在独立的.py文件中,通过模块可以把程序分解为小的、具有独立功能的模块,这样不仅可以提高代码的可读性和可维护性,而且可以更好地组织和管理代码。
Python中的模块可以直接通过import
语句导入,语法如下:
这里的module_name
就是要导入的模块名称,可以是Python标准库中的模块,也可以是第三方库或自己编写的模块。
在使用模块时,我们可以选择只导入其中的某些函数或变量,而不是全部导入,这样可以避免命名冲突和减少内存占用。语法如下:
这里的
function_name
和variable_name
就是要导入的函数或变量名称,多个名称之间用逗号分隔。
为了避免模块名称过长或命名冲突,我们可以给模块起一个别名,然后使用别名来访问模块中的函数和变量。语法如下:
当使用import
语句导入模块时,Python会在搜索路径中找到第一个匹配的模块,并将其加载到内存中。如果在程序运行时发现需要更新该模块,可以通过重新加载该模块来更新它。
要重新加载模块,可以使用内置函数reload()
。reload()
函数将重新加载之前已经导入的模块,以便在模块已更改时更新它。
使用reload()
函数需要导入内置模块importlib
,如下所示:
使用reload()
函数的方法如下:
为了演示如何重载模块,请考虑以下情况。假设有一个名为my_module
的模块,它包含以下代码:
现在,在另一个文件中导入并使用该模块:
现在,如果更改my_module.py
文件中的x
值并重新运行main.py
,您将看到输出仍然是10,即使已经更改了my_module.py
文件中的值。这是因为Python已经将my_module
模块加载到内存中,因此不会重新读取文件。
要使更改生效,需要重新加载该模块。下面是如何通过重载my_module
模块来实现:
通过重载my_module
模块,现在已经成功更新了x
的值,因此输出为20。
需要注意的是,reload()
函数是在Python 2.x中引入的,在Python 3.x中被移到了内置模块importlib
中。此外,由于模块的导入只在程序执行的时候发生一次,因此模块的重载只有在动态地重新加载模块时才能生效。
另外,模块重载也可能会引入一些意想不到的行为,因为重新加载模块会导致新的模块对象生成,这可能会导致某些意外的结果,特别是当模块是在其他模块之间共享的全局状态时。
当我们编写大型的程序时,需要将相关的模块组织成一个包。Python 的包就是文件夹(目录),文件夹下必须有一个 __init__.py
文件,该文件夹称之为包。我们可以使用包来组织模块,这样可以避免模块名字冲突,也使我们更好地组织代码。
我们可以使用点号(.)来导入包中的模块。例如,假设有以下包结构:
我们可以这样导入包中的模块:
当我们在包中使用相对导入时,需要使用 .
表示相对位置。例如,假设我们在 my_package
包下的 module1
中导入 module2
,则可以使用以下方式:
如果要使用父级包的模块,则可以使用两个点号(..)表示:
__init__.py
文件每个包目录下都必须包含一个名为 __init__.py
的文件,这个文件可以是空文件,也可以包含包的初始化代码。这个文件在包被导入时被执行。
例如,我们可以在 my_package
包的 __init__.py
中定义一些变量:
然后在其他模块中导入这个包并使用 PI
变量:
当我们在包中使用相对导入时,需要特别注意一些事项:
下面是一个使用包的示例:
在上面的示例中,我们导入了 module1
中的所有函数到包的 __init__.py
中,并在主程序中导入了整个包。因此,我们可以使用 my_package.func1()
来调用 module1
中的函数,但是尝试调用module2
中的函数时,会出现AttributeError
,因为module2
中没有定义名为func1
的函数。此时可以使用from ... import ...
语句重新导入需要的函数,或者使用importlib.reload
重新加载module2
模块。