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目录中创建一个名为
然后你可以做:
1 | from Models.user import User |
您可以在
您必须在
然后你可以做:
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目录中,所有文件都应该是金色的。
如何写出参数
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"文件夹中都有
下面的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导入用户。