概要:在本教程中,你将学习如何使用 __all__
变量在模块中定义 Python 私有函数。
假设你有一个名为 mail.py
的模块,其中包含两个函数 send()
和 attach_file()
:
def send(email, message):
print(f'Sending "{message}" to {email}')
def attach_file(filename):
print(f'Attach {filename} to the message')
并且你希望仅将 send()
函数暴露给其他模块,而不暴露 attach_file()
函数。换句话说,你希望 attach_file()
函数是私有的,并且不能从 mail
模块外部访问。
需要注意的是,为了简单起见,我们仅在函数中打印一些文本。
如果其他模块使用 import *
语句,如下所示:
from mail import *
你可以通过在函数名前加一个下划线 (_
) 来使其成为私有函数。例如:
def send(email, message):
print(f'Sending "{message}" to {email}')
def _attach_file(filename):
print(f'Attach {filename} to the message')
从 mail.py
文件中,如果你使用 from mail import *
从 mail
模块导入,那么你只能看到 send()
函数:
from mail import *
send('test@example.com','Hello')
换句话说,你将无法从主模块访问 _attach_file()
函数。如果你尝试调用 _attach_file()
函数,将会得到一个错误。
另一种使 attach_file()
函数变为私有的方法是使用 __all__
变量。通过这种方式,你不需要在函数名前加下划线 _
) 来使其成为私有函数。
__all__
指定了一个函数(也包括变量和其他对象)列表,这些函数对其他模块是可用的。换句话说,你可以通过不在 __all__
变量中列出某个函数来使其成为私有函数。
以下是在 mail
模块中使用 __all__
变量来使 send()
函数成为公有函数,而 attach_file()
函数成为私有函数的示例:
# mail.py
__all__ = ['send']
def send(email, message):
print(f'Sending "{message}" to {email}')
def attach_file(filename):
print(f'Attach {filename} to the message')
从 main.py
模块中,你也无法像之前那样访问 attach_file()
函数:
# main.py
from mail import *
send('test@example.com', 'Hello')
正如在模块教程中提到的import *
并不是一个好的实践,并且经常会导致错误。然而,你仍然可以通过使用包来利用它。
首先,创建一个名为 mail
的包,其中包含 __init__.py
文件,并在 mail
包中创建 email.py
模块:
├── mail
| ├── email.py
| └── __init__.py
└── main.py
第二,将以下代码放入 email.py
文件中:
# email.py
__all__ = ['send']
def send(email, message):
print(f'Sending "{message}" to {email}')
def attach_file(filename):
print(f'Attach {filename} to the message')
第三,使用 import *
并在 __init__.py
中将 send()
函数添加到 __all__
变量中;
from .email import *
__all__ = email.__all__
通过这样做mail
包仅暴露 email.__all__
变量中指定的 send()
函数。它从外部隐藏了 attach_file()
函数。
从 main.py
文件中,你可以导入 mail
包并像这样使用 send()
函数:
# main.py
import mail
mail.send('test@example.com','Hello')
或者,你可以从 mail
包中导入 send()
函数:
# main.py
from mail import send
send('test@example.com','Hello')
总结
要在 Python 中将函数设为私有:
首先,创建一个包含
__init__.py
文件的包。其次,不要在
__all__
变量中指定该函数。然后,在包的
__init__.py
文件中从模块导入所有符号,并使用__all__
变量仅暴露公有函数。