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
为您管理名称空间。