无法从其他文件夹导入python

Can't get Python to import from a different folder

我似乎无法让python在子文件夹中导入模块。当我试图从导入的模块中创建类的实例时,会得到错误,但导入本身会成功。这是我的目录结构:

1
2
3
4
Server
    -server.py
    -Models
        --user.py

以下是server.py的内容:

1
2
3
4
5
6
7
from sys import path
from os import getcwd
path.append(getcwd() +"\\models") #Yes, i'm on windows
print path
import user

u=user.User() #error on this line

和用户

1
2
3
4
5
6
7
8
class User(Entity):
    using_options(tablename='users')

    username = Field(String(15))
    password = Field(String(64))
    email    = Field(String(50))
    status   = Field(Integer)
    created  = Field(DateTime)

错误是:attributeError:"module"对象没有属性"user"


我相信您需要在models目录中创建一个名为__init__.py的文件,以便python将其视为一个模块。

然后你可以做:

1
from Models.user import User

您可以在__init__.py中包含代码(例如一些不同类需要的初始化代码),也可以将其留空。但一定在那里。


您必须在Models子文件夹上创建__init__.py。文件可能为空。它定义了一个包。

然后你可以做:

1
from Models.user import User

在这里的python教程中阅读关于它的所有内容。

这里还有一篇关于Python项目文件组织的好文章。


import user

u=user.User() #error on this line

由于缺乏上述的初始化,您会期望出现一个重要的错误,这将使问题更加清楚。

因为"用户"也是标准库中的一个现有模块,所以您无法获取。您的import语句将获取该语句,并尝试在其中查找用户类;这不存在,只有这样才能得到错误。

一般来说,最好是绝对进口:

1
import Server.Models.user

为了避免这种歧义。实际上,从python2.7的"import user"来看,它根本就不会与当前模块相关。

如果您真的想要相对导入,可以在python2.5和更高版本中显式地使用一些难看的语法:

1
from .user import User

当没有标准包结构时,导入位于父文件夹上的模块的正确方法是:

1
2
3
import os, sys
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.dirname(CURRENT_DIR))

(您可以合并最后两行,但这样更容易理解)。

这个解决方案是跨平台的,一般情况下不需要修改。


你失踪了。从python教程:

The __init__.py files are required to
make Python treat the directories as
containing packages; this is done to
prevent directories with a common
name, such as string, from
unintentionally hiding valid modules
that occur later on the module search
path. In the simplest case,
__init__.py can just be an empty file, but it can also execute initialization
code for the package or set the
__all__ variable, described later.

把一个名为uu init_uuu.py的空文件放在models目录中,所有文件都应该是金色的。


如何写出参数os.path.dirname……命令?

1
2
3
import os, sys
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.dirname(CURRENT_DIR))


在仔细阅读了上面这些贡献者给出的答案之后——Zorglub29、Tom、Mark、Aaron McMillin、Lucasamaral、Joeyzhao、Kjeld Flarup、Procylinser、Martin.Zaenker、Tooty44,并调试了我所面临的问题,我发现了一个不同的用例,正是由于这个问题我才面临这个问题。因此,在下面添加我的意见供任何人参考。

在我的代码中,我有一个类的循环导入。例如:

1
2
3
4
5
src
 |-- utilities.py (has Utilities class that uses Event class)  
 |-- consume_utilities.py (has Event class that uses Utilities class)
 |-- tests
      |-- test_consume_utilities.py (executes test cases that involves Event class)

当我尝试执行python-m py test tests/test_utilities.py以执行用test_utilities.py编写的uts时,出现了以下错误。

1
2
3
4
5
6
7
8
ImportError while importing test module '/Users/.../src/tests/test_utilities.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
tests/test_utilities.py:1: in <module>
    from utilities import Utilities
...
...
E   ImportError: cannot import name 'Utilities'

我解决错误的方法是重新分解代码以移动循环导入类中的功能,以便删除类的循环导入。

注意,我的"src"文件夹和"tests"文件夹中都有__init__.py文件,但仍然可以通过重新分解代码来消除"importerror"。

下面的stackoverflow链接提供了更多关于Python中循环依赖性的详细信息。


我的首选方法是在包含其他模块使用的模块的每个目录上都有uuu init_uuuy.py,并且在入口点中重写sys.path,如下所示:

1
2
3
4
5
6
def get_path(ss):
  return os.path.join(os.path.dirname(__file__), ss)
sys.path += [
  get_path('Server'),
  get_path('Models')
]

这使指定目录中的文件对导入可见,并且我可以从server.py导入用户。