“_func”即使在 __all__

问题描述 投票:0回答:1

我正在使用Python 2。

我发现,当

__all__
未声明
时(即仅使用
_functions
但未明确定义
__all__),from module import *
默认不会传递
__all__
(下划线的“内部”函数)。但是,我还看到即使将 
_functions
 添加到 
__all__
,也没有通过。

为了找到这个问题的答案,我在问题中遗漏了哪些词语?这是 Python 3 中持续存在的“问题”(或预期行为?)吗?

我的例子是:

我正在创建内部和外部功能的组合。目前我对这个问题的绕过是将

_functions

(下划线函数,又名“内部函数”,
重命名为无下划线)放入._internal_module_folder
中,然后将
._internal_module_folder
导入到
external_module
中并添加外部函数添加到 
__all__
external_module
,但忽略内部函数。

所以我原来的树(有问题)看起来像这样:

modules_folder/ |---- __init__.py |---- external_module.py |---- _internal_module_folder/ |-------- __init__.py |-------- _internal_module.py
地点:

  1. modules_folder/_internal_module_folder/__init__.py
     包含:
from ._internal_module import * # Should import _functions from __all__??

  1. modules_folder/_internal_module_folder/internal_module.py
     包含:
__all__ = [ # functions: 'extl_func1', # _functions: '_intl_func1', ] def extl_func1(*args, **kwargs): pass def _intl_func1(*args, **kwargs): pass

  1. modules_folder/__init__.py
    包含:
from .external_module import *

  1. modules_folder/external_module.py
    包含:
from ._internal_module_folder import * __all__ = [ # functions: 'extl_func1', # from _internal_module_folder 'extl_func2', ] def extl_func2(*args, **kwargs): _intl_func1() def _intl_func2(*args, **kwargs): pass
运行时出现错误,指出 

_int_func1

 不存在,即使它明确位于 
__all__
 中:

NameError: name '_intl_func1' is not defined


我的解决方案:

    我将
  1. _intl_func
     重命名为 
    intl_func
    
    
  2. 我将
  3. modules_folder/__init__.py
     中的导入更改为 
from . import _internal_module as im

    然后我给调用时的内部函数起了别名
from . import _internal_module_folder as im __all__ = [ # functions: 'extl_func1', # from _internal_module_folder 'extl_func2', ] # Aliasing the internal module functions to pass to __all__: extl_func1 = im.extl_func1 def extl_func2(*args, **kwargs): im.intl_func1() def _intl_func2(*args, **kwargs): pass
此 PEP 8 已获批准吗?

总结:将

_function

放入
__all__
,但没有传递到
from module import *

python module python-import python-2.x pep8
1个回答
0
投票
这是预期的行为。前面带有下划线的内部函数被赋予“弱内部使用”指示符,这意味着它们不会通过

__all__

 传递,即使在 
__all__
 中明确命名。

此信息来自 PEP 8 (

https://peps.python.org/pep-0008/#descriptive-naming-styles)

解决方案的关键部分是从导入全部更改,即:

from ._internal_module_folder import *
使用别名导入模块(也可以不使用别名!):

from . import _internal_module_folder as im # with module aliasing
注意:导入模块时,无需将 

_intl_func1

 重命名为 
intl_func1
,因为导入模块会绕过 
__all__

但是,将外部函数(前面没有下划线的函数)从

_internal_module_folder

 传递到 
__all__
 中的 
external_module.py
 列表并不是公开外部函数的首选方法,因为很难找到在哪里如果稍后更改函数名称,则会出现错误!导入应由 
__init__.py 控制(根据“Dead Simple Python”,2023 年,Jason C. McDonald,第 87-88 页)
因此,
modules_folder/__init__.py

应更改为包含两个模块的外部函数:

from .external_module import *
from ._internal_module_folder import *

在这种情况下
modules_folder/external_module .py
应更改为:

from . import _internal_module_folder as im
__all__ = [
    # functions:
    'extl_func2', # Only list the external functions from THIS file
    ]

def extl_func2(*args, **kwargs):
    im.intl_func1
def _intl_func2(*args, **kwargs):
    pass

或者也可以直接在
modules_folder/external_module .py
中导入具体的内部函数,简化

_intl_func1

函数调用:
from ._internal_module_folder import _intl_func1 # This does not access the __all__ list!
__all__ = [
    # functions:
    'extl_func2',
    ]

def extl_func2(*args, **kwargs):
    _intl_func1()
def _intl_func2(*args, **kwargs):
    pass


© www.soinside.com 2019 - 2024. All rights reserved.