2017-01-15 48 views
2

我目前在做一个个人编码项目,我想建立一个模块,但我不知道为什么我的结构不上班的路上它应该:自定义Python模块结构

\mainModule 
    __init__.py 
    main.py 
    \subModule_1 
     __init__.py 
     someCode_1.py 
     someCode_2.py 
    \subModule_2 
     __init__.py 
     otherCode.py 

我希望能够从main.py运行下面的代码:

>>> from subModule_1 import someCode_1 
>>> someCode_1.function() 
"Hey, this works!" 
>>> var = someCode_2.someClass("blahblahblah") 
>>> var.classMethod1() 
>>> "blah blah blah" 
>>> from subModule2 import otherCode 
>>> otherCode("runCode","#ff281ba0") 

然而,当我尝试导入someCode_1,例如,它返回一个AttributeError,我真的不知道为什么。它与__init__.py文件有关吗?

修订

  • 最小的,完整的和可核查的(我希望...)

    \mainDir 
        __init__.py # blank file 
        main.py 
        \subDir 
         __init__.py # blank file 
         codeFile.py 
    

    使用此...

    #main.py file 
    import subDir 
    subDir.codeFile.function() 
    

    这...

    #codeFile.py file 
    def function(): 
        return "something" 
    

    ...它返回上面提到的同样的问题**。

**确切的错误是:

Traceback (most recent call last): 
    File "C:\...\mainDir\main.py", line 2, in <module> 
    subDir.codeFile.function() 
AttributeError: module 'subDir' has no attribute 'codeFile' 

贷@jonrsharpe:谢谢你向我展示如何正确使用堆栈溢出。

+2

请提供[MCVE。另外你似乎在说你想从'main.py'“*中运行一个交互式会话*,这并不完全合理。 – jonrsharpe

+1

可能是由导入时执行的'someCode_1'中的某些模块级代码引起的。确切的错误信息是什么? – schwobaseggl

+0

@jonrsharpe对不起,我的意思是使用解释器编译并运行'main.py'(对不起,菜鸟错误) – BUZZYSIN

回答

1

有两个选项可以使这项工作。

无论是这样的:

from subdir import codeFile 
codeFile.function() 

或者:

import subdir.codeFile 
subdir.codeFile.function() 
+0

是的,这工作正常,谢谢 – BUZZYSIN

1

当你import subDir,它做了三两件事:

  1. 执行mainDir/subDir/__init__.py的代码(即在这种情况下,什么也不做,因为这个文件是空的)
  2. subDir下的进口所产生的模块本地,这又将其作为mainDir模块的属性;
  3. sys.modules字典中全局注册新的导入(因为import正在从父模块mainDir执行,因此此注册的目的名称已完成为'mainDir.subDir');

它所做的做的,因为它没有被告知,是进口subDir.codeFile。因此,codeFile.py中的代码尚未运行,名称codeFile尚未导入到mainDir.subDir的名称空间中。因此当试图访问它时AttributeError。如果您要添加以下行至mainDir/subDir/__init__.py那么它会工作:

import codeFile 

具体来说,这将:

  1. 运行codeFile.py
  2. 的代码添加所产生的模块的属性mainDir.subDir模块
  3. 存储对sys.modules的另一个条目的引用,此时名称为mainDir.subDir.codeFile

你也可以实现从高了模块的层次结构相同的效果,说import subDir, subDir.codeFile,而不是仅仅import subDirmainDir.main源文件。

注意:当你在命令行或IDE进行测试,确保您的当前工​​作目录(os.getcwd()查询,使用os.chdir(wherever)改变)既不是mainDir也不subDir。从其他地方工作 - 例如。 mainDir的父目录。在模块内部工作会导致意想不到的结果。

+0

这非常有道理 - 我现在正在修改它以使其正常工作(我不知道导入关键字是如何工作的,但是这为我清除了很多烟雾) – BUZZYSIN

+0

问题 - 如果我不想要让我当前的工作目录是'main.py'(你准确猜测它会是),“我会在哪里运行解释器?它甚至是_matter_? – BUZZYSIN

+0

不幸的是,我将'import codeFile'放入'mainDir \ subDir \ __ init __。py'中时出现错误:'ModuleNotFoundError:No module named'codeFile'' – BUZZYSIN