Python 如何为同一命名空间获取第二个_uinit__uu.py execute

Python 如何为同一命名空间获取第二个_uinit__uu.py execute,python,python-2.7,namespaces,package,python-import,Python,Python 2.7,Namespaces,Package,Python Import,这是我的目录结构 . |-- path1 | `-- mynms | |-- __init__.py | `-- app1 | |-- __init__.py | `-- foo.py |-- path2 | `-- mynms | |-- __init__.py | `-- app2 | |-- __init__.py | `-- bar.py `-- use

这是我的目录结构

.
|-- path1
|   `-- mynms
|       |-- __init__.py
|       `-- app1
|           |-- __init__.py
|           `-- foo.py
|-- path2
|   `-- mynms
|       |-- __init__.py
|       `-- app2
|           |-- __init__.py
|           `-- bar.py
`-- user.py
文件内容:

$ cat user.py
#!/usr/bin/python

import sys
sys.path.append('path1')
sys.path.append('path2')

from mynms.app2.foo import foo
from mynms.app2.bar import bar

foo()
bar()

$ cat path1/mynms/__init__.py;echo ==============;cat path2/mynms/__init__.py
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)

print "I am path1/mynms/__init__.py"
==============
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)

print "I am path2/mynms/__init__.py"

$ cat path1/mynms/app1/foo.py; echo ============; cat path2/mynms/app2/bar.py
def foo():
  print "foo!"
============
def bar():
  print "bar!"
问题:当我运行user.py时,我只得到path1/\uuuuu init\uuuuuu.py的输出,而没有得到path2的输出。有没有办法解决这个问题?

$ ./user.py
I am path1/mynms/__init__.py        -----> Why is 'I am path2/mynms/__init__.py not printed?
foo!
bar!

当您从mynms.app2.foo import foo编写
import mynms.app2.foo
时,Python会执行以下操作:

  • 通过查找在路径1中找到的文件
    mynms/\uuuu init\uuuuu.py
    导入
    mynms
  • 通过查找文件导入
    mynms.app1
    (或
    mynms/app1/\uuu init\uuuuuu.py
  • 通过查找
    mynms/app1/foo.py导入
    mynms.app1.foo
    (或
    mynms/app1/foo/\uuuu init\uuuuuuuu.py
在下一条导入语句中,
import mynms.app2.bar
,Python执行以下操作:

  • 导入
    mynms
    -它已导入,因此无需执行任何操作。(您可以检查
    sys.modules['mynms']
    以查看它是否已导入。如果未导入,它将引发
    KeyError
  • 导入
    mynms.app2
    -同样,此文件已导入
  • 通过读取路径2中的文件
    mynms/app2/bar.py
    导入
    mynms.app2.bar
Python没有(合理的)方法从两个不同的文件导入
mynms
模块两次


如果您有初始化代码,则需要将它们放在模块
mynms.app1
mynms.app2
中,以便它们具有不同的名称。i、 e.文件
mynms/app1/\uuuu init\uuuuuuuuupy
mynms/app2/\uuuuuuuu init\uuuuuuuupy
我同意其余的评论-这是糟糕的代码结构,应该尽快重构。但是,如果您真的、真的、真的不能或还不能,那么您可以使用标准库中的imp模块来处理导入内部构件:

例如,您可以通过执行以下操作导入不在常规python模块搜索路径中的文件:

/Users/me/test.py:

def run_foo():
  print "hi got here" 
还有另一个脚本:

import imp
foo = imp.load_source("foo", "/Users/me/test.py")
foo.run_foo()

同样,您正在以这种方式与Python对抗,而不是使用它。但这是一个很好的诀窍

正如Martijn Pieters在评论中提到的,Python 2不支持作为包集合分发的包。但是,如果您使用
setuptools
,您可以模拟这样的软件包(很可能是这样)

唯一的问题是包应该具有正确的元信息,这样
setuptools
就可以将多个子包连接到一个虚拟的单个包中。这些信息通常会传递到
setup.py
中的
setup()
函数,并在安装后保存在
站点包
目录中。这意味着那些分发包的人无论如何都应该做一些事情来正确地准备它们,而你很难仅仅把它们放在
路径中
来让它们工作


是指向相应文档的链接。准备好花些时间,因为PEAK文档并不总是足以快速启动。

您有两个名称相同的软件包,这通常是不受欢迎的。为什么您的测试用例包必须使用相同的名称?你能重命名第二个吗?名称
testcase
有误导性,让我更改一下。出于其他原因,我不能将它们更改为不同的名称空间。它们是由同一个开发团队开发的两个应用程序,但出于部署目的,它们必须处于不同的层次结构中
setuptools
确实添加了名称空间支持,但要复制这种行为需要大量的黑客攻击。当我有更多时间时,我可以总结一下
setuptools
在某个时候所做的工作,但您也可以直接使用它来打包项目,并让
setuptools
为您管理名称空间。