如何定义从一个模块导入的内容?

3
我有这样的目录结构:
└── stuff
    ├── __init__.py
    └── substuff
        ├── imp.py
        └── __init__.py

stuff/__init__.py的内容如下:

from stuff.substuff.imp import foo, bar

类似这样的 stuff/substuff/__init__.py

from stuff.substuff.imp import foo, bar

__all__ = [
    'foo',
    'bar'
]

stuff/substuff/imp.py 包含内容。

import pandas as pd
import numpy as np

__all__ = ['foo', 'bar']


def foo():
    return {'foo': np.sqrt(2)}


def bar():
    return ('bar', 'xyz')


def _helper():
    return True

如果我现在执行

from stuff.substuff import imp

当检查 imp 时,我看到了 barfoo,以及 pdnp

如何实现用户只能看到 barfoo,而不能看到 pdnp?一种解决方案似乎是将它们导入为 _pd_np,但我想知道是否有比这更好的“美观”的解决方案。


1
请查看这个已经回答的问题 - 您应该在这里找到您想要实现的答案以及许多实现方法。链接 - shreyashag
@shreyashag:在我谷歌搜索时确实错过了这个;第一个答案使用了下划线,而我想避免它,第二个答案似乎可以解决问题。 - Cleb
1个回答

1
首先,注意到__all__并不会阻止任何模块符号(函数、类等)被直接导入。请查看这篇惊人的文章以获取更多细节。它只为from stuff.substuff.imp import *设置行为,而不是显式模块导入(文档)。
此语句将仅如你所期望地导入foobar
from stuff.substuff import *

此外,您已经将直接从substuff包导入限制为foobar

from stuff.substuff import foo  # successfully imported
from stuff.substuff import pd  # import error

是的,但它并没有解决 from stuff.substuff import imp 的问题,其中 pd 仍然存在。 - Cleb
你是否需要限制这些导入,或者默认只导入有用的内容? - Oleh Rybalchenko
用户应该只能看到__all__中定义的内容;__all__仅在使用通配符导入时才会被使用,我只是想知道如何将其限制在此范围内。 - Cleb
那么你可以让用户直接从substuff包中导入(只导入了内部模块中从__init__显式导入的内容)。这种方法对你有用吗?当然,用户仍然可以直接导入子模块,但我相信你无法以“优雅”的方式阻止这种情况。 - Oleh Rybalchenko
1
我认为上面的链接很好地展示了如何做到这一点;我肯定想要防止它以保护自己和用户免受搞笑的事情发生;) 现在已经点赞了。 - Cleb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接