目录:
__init__.py
的基本用法简化模块访问 使用 __all__
优化导入
__init__.py
的基本用法
标识为包:最简单的__init__.py
文件可能为空,它的存在只是为了告诉Python解释器该目录应该被视为一个包。
初始化代码:你也可以在__init__.py
文件中编写Python代码。当你的包或其子模块被导入时,这些代码会被执行。
控制包的导入行为:通过在__init__.py
中定义__all__
列表,你可以指定哪些模块应该从from package import *
语句中被导入。
简化模块访问
当你有一个包含多个模块的包时,每次都使用package.module
这样的长路径来引用包内的成员可能会变得很繁琐。为了解决这个问题,你可以在__init__.py
文件中从各个模块导入你需要的函数或类,这样用户就可以直接通过包名来访问这些成员了。
假设我们的my_package
包结构如下:
my_package/
__init__.py
module1.py
module2.py
其中module1.py
和module2.py
的内容分别为:
# my_package/module1.py
def say_hello():
print("你好!我是module1")
# my_package/module2.py
class MyClass:
def greet(self):
print("您好!我是来自module2的MyClass")
我们可以利用__init__.py
来简化对这些模块成员的访问:
# my_package/__init__.py
from .module1 import say_hello # 从module1导入say_hello函数
from .module2 import MyClass # 从module2导入MyClass类
# 可以在这里定义其他全局变量或执行初始化操作
sh_myueren = "山海摸鱼人" # 定义一个中文字符串
def package_greet(name=sh_myueren):
"""打印问候信息"""
print(f"你好, {name}!")
通过上述设置,当我们在外部程序中导入my_package
时,可以直接使用say_hello()
和MyClass
而无需指定完整的模块路径。
外部程序示例
import my_package
# 直接调用my_package中的say_hello函数
my_package.say_hello()
# 创建my_package.MyClass的一个实例
obj = my_package.MyClass()
obj.greet()
# 调用自定义的greet函数
my_package.package_greet()
这段代码将输出:
你好!我是module1
您好!我是来自module2的MyClass
你好, 山海摸鱼人!
这种方式不仅使代码更加简洁,也提高了用户体验,因为他们只需要记住包名即可轻松访问所需的功能。
使用__all__
优化导入
除了直接导入特定的函数或类之外,我们还可以通过定义__all__
列表来控制from my_package import *
语句的行为。这有助于避免意外地导入不必要的名称空间污染。
修改__init__.py
文件如下:
# my_package/__init__.py
from .module1 import say_hello
from .module2 import MyClass
# 只允许导入这两个名称
__all__ = ['say_hello', 'MyClass']
# 其他定义保持不变
sh_myueren = "山海摸鱼人"
def package_greet(name=sh_myueren):
print(f"你好, {name}!")
外部程序修改
from my_package import *
# 直接调用say_hello函数
say_hello()
# 创建MyClass的一个实例
obj = MyClass()
obj.greet()
# 调用自定义的greet函数
package_greet()
这样,当我们执行from my_package import *
时,只有say_hello
和MyClass
会被导入到当前命名空间中,其他如sh_myueren
或package_greet
不会被导入。