Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python 2.7中从导出列表中隐藏名称_Python_Python 2.7 - Fatal编程技术网

在Python 2.7中从导出列表中隐藏名称

在Python 2.7中从导出列表中隐藏名称,python,python-2.7,Python,Python 2.7,我正在用Python编写一个具有以下模块结构的小程序包 package/ __init__.py cls1.py cls2.py cls3.py mod1.py mod2.py 其中每个clsN.py中都有一个类clsN,每个modN.py包含使用这些类的各种函数。我希望我的导入结构看起来像 package package.Cls1 package.Cls2 package.Cls3 package.mod1 package.mod1.func1 ... package

我正在用Python编写一个具有以下模块结构的小程序包

package/
  __init__.py
  cls1.py
  cls2.py
  cls3.py
  mod1.py
  mod2.py
其中每个
clsN.py
中都有一个类
clsN
,每个
modN.py
包含使用这些类的各种函数。我希望我的导入结构看起来像

package
package.Cls1
package.Cls2
package.Cls3
package.mod1
package.mod1.func1
...
package.mod2
package.mod2.func2
...

而不会污染名称空间。现在我的问题是,我可以通过
package.Cls1
package.Cls1.Cls1
访问这些类中的任何一个,我还可以访问
package/Cls1.py
中定义的所有内容(包括导入)。我已经尝试设置
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。有没有办法防止Python将
clsN
显示为子模块?甚至只是一种在这些文件中隐藏导入的方法?我不想让我的库的用户有两种方式进入每个类。

首先,我建议不要太担心从哪里可以看到什么。如果用户试图访问
package.mod1.Cls1
,如果它正常工作,真的会有问题吗?Python通常是一种非常宽容的语言,试图隐藏东西往往会带来很多麻烦

这就是说,如果您想减少非标准访问的可能性,一个好方法是使用可选名称(从下划线开始)将类导入到模块中。名称开头带有单下划线的变量不会从import*
导入,也不会显示在
dir
列表中。以下是您可以做到这一点的方法:

mod1.py
中:

from .Cls1 import Cls1 as _Cls1
from .Cls2 import Cls2 as _Cls2
from .Cls3 import Cls3 as _Cls3

然后在模块代码中使用下划线名称。其他想要访问这些类的代码可能会在它们的“官方”位置下找到它们。

stdlib有两种处理此类情况的方法

第一个很简单:只需使用下划线前缀将私有模块标记为private,就像将任何其他属性标记为private一样。这并没有对用户隐藏它们,但它确实意味着用户不应该使用它们(并且可能会阻止像iPython或PyDev这样的东西将它们作为完成提供),这通常就足够了

唯一真正的问题是,模块名称上的下划线前缀也倾向于暗示它们是本机加速器。换句话说,用户可能期望
\u foo
foomodule.c
实现,而不是
\u foo.py

另一种选择是不从子模块导入名称、其他、yetanother导入它们,或者在模块末尾导入它们。您明确希望
package.Cls1
的类型与
package.Cls1.Cls1
的类型相同,这意味着这正是您想要的


如果用户愿意,仍然可以显式导入它们。但是Python通常不会给你任何阻止恶意或故意愚蠢的方法,你也不应该尝试。

你可以使用各种技巧,但通常最简单的答案与其他私有属性(如方法)相同:只需在私有模块前面加上
\ucode>,这应该足以阻止人们使用它们。@abarnert我已经想到了这一点,但我正试图让事情尽可能简单。这是一个库,不一定熟悉Python(在工作场所使用多种语言的问题)的人将对它进行审查,我知道我会被告知删除下划线,因为它看起来很奇怪。然而,如果这被普遍认为是“蟒蛇式”的做事方式,我可以用它作为一个足够有力的论据。编辑:因为我没有点击shift+ENTER,现在我已经发布了它,我发现我的答案与@abarnert的评论基本相同。不过,我确实认为我的介绍段落很重要:不要担心可见性问题,只需记录对象的“正确”位置,让用户做他们想做的事情@贝克利尔:对下划线的抱怨就像有Python背景的人告诉C程序员去掉所有分号,因为它们看起来很奇怪。你为什么不能告诉他们“不,这是标准的做法”?嗯,这看起来很奇怪,目的是为了“吓唬人们不要使用它”,对吗?此外,如果有人试图在您的Python代码上应用Python不友好的需求,您会遇到更大的问题。