想象一下这个目录结构:

app/
   __init__.py
   sub1/
      __init__.py
      mod1.py
   sub2/
      __init__.py
      mod2.py

我正在编写mod1,我需要从mod2中导入一些东西。我该怎么做呢?

我试过…sub2导入mod2,但我得到了一个“尝试相对导入非包”。

我搜索了一下,但只找到了“sys”。路径操纵“黑客”。没有干净的方法吗?


编辑:我所有的__init__.py目前是空的

Edit2:我试图这样做是因为sub2包含跨子包共享的类(sub1、subX等)。

Edit3:我正在寻找的行为与PEP 366中描述的相同(感谢John B)


当前回答

用例子解释nosklo的答案

注意:所有__init__.py文件都是空的。

main.py
app/ ->
    __init__.py
    package_a/ ->
       __init__.py
       fun_a.py
    package_b/ ->
       __init__.py
       fun_b.py

app - package_a fun_a . py

def print_a():
    print 'This is a function in dir package_a'

app - package_b fun_b . py

from app.package_a.fun_a import print_a
def print_b():
    print 'This is a function in dir package_b'
    print 'going to call a function in dir package_a'
    print '-'*30
    print_a()

main.py

from app.package_b import fun_b
fun_b.print_b()

如果你运行$ python main.py,它会返回:

This is a function in dir package_b
going to call a function in dir package_a
------------------------------
This is a function in dir package_a

Main.py执行如下操作 Fun_b.py从app.package_a。Fun_a import print_a

package_b文件夹中的文件使用package_a文件夹中的文件,这就是你想要的。对吧? ?

其他回答

很不幸,这是一个系统。路径hack,但它工作得很好。

我在另一个层遇到了这个问题:我已经有一个指定名称的模块,但它是错误的模块。

我想做的是以下(我从模块是模块3):

mymodule\
   __init__.py
   mymodule1\
      __init__.py
      mymodule1_1
   mymodule2\
      __init__.py
      mymodule2_1


import mymodule.mymodule1.mymodule1_1  

注意,我已经安装了我的模块,但在我的安装中,我没有“mymodule1”

我会得到一个ImportError,因为它试图从我安装的模块中导入。

我尝试了一个sys。path。追加,这行不通。sys.path.insert起作用了吗

if __name__ == '__main__':
    sys.path.insert(0, '../..')

有点像黑客,但都能用上了! 所以请记住,如果你想要你的决定覆盖其他路径,那么你需要使用sys.path。插入(0,pathname)让它工作!这对我来说是一个非常令人沮丧的症结,很多人说要使用“追加”功能到sys。路径,但如果你已经定义了一个模块,这就行不通了(我发现这是非常奇怪的行为)

def import_path(fullpath):
    """ 
    Import a file with full path specification. Allows one to
    import from anywhere, something __import__ does not do. 
    """
    path, filename = os.path.split(fullpath)
    filename, ext = os.path.splitext(filename)
    sys.path.append(path)
    module = __import__(filename)
    reload(module) # Might be out of date
    del sys.path[-1]
    return module

我使用这个代码片段从路径导入模块,希望有帮助

你必须将模块的路径附加到PYTHONPATH:

export PYTHONPATH="${PYTHONPATH}:/path/to/your/module/"

“Guido将包中运行的脚本视为反模式”(拒绝 pep - 3122)

我花了很多时间试图找到一个解决方案,阅读Stack Overflow上的相关文章,并对自己说“一定有更好的方法!”看起来没有。

我把这个写在这里供我自己参考。我知道这不是好的Python代码,但我需要一个我正在进行的项目的脚本,我想把脚本放在脚本目录中。

import os.path
import sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))