繁体   English   中英

无法从其他文件夹导入Python

[英]Can't get Python to import from a different folder

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

Server
    -server.py
    -Models
        --user.py

这是server.py的内容:

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

和user.py:

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将其视为一个模块。

然后你可以这样做:

from Models.user import User

您可以在__init__.py包含代码(例如,几个不同类需要的初始化代码)或将其留空。 但它一定存在。

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

然后你可以这样做:

from Models.user import User

阅读所有关于它在python教程, 这里

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

导入用户

u = user.User()#error在这一行

由于缺少上面提到的__init__,你会发现一个ImportError可以使问题更加清晰。

你没有得到一个,因为'user'也是标准库中的现有模块。 你的import语句抓住那个并尝试在其中找到User类; 那是不存在的,只有这样才能得到错误。

通常一个绝对的导入是一个好主意:

import Server.Models.user

避免这种模棱两可。 事实上,从Python 2.7'导入用户'看起来根本不会与当前模块相关。

如果你真的想要相对导入,你可以在Python 2.5中使用稍微丑陋的语法显式地使用它们:

from .user import User

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

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

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

该解决方案是跨平台的,并且通用性足以在其他情况下不需要修改。

你错过了__init__.py。 从Python教程:

需要__init__.py文件才能使Python将目录视为包含包; 这样做是为了防止具有通用名称的目录(例如字符串)无意中隐藏稍后在模块搜索路径上发生的有效模块。 在最简单的情况下,__ init__.py可以只是一个空文件,但它也可以执行包的初始化代码或设置__all__变量,稍后描述。

将名为__init__.py的空文件放在Models目录中,所有文件都应该是黄金的。

你怎么写出os.path.dirname ....命令的参数?

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

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

def get_path(ss):
  return os.path.join(os.path.dirname(__file__), ss)
sys.path += [
  get_path('Server'), 
  get_path('Models')
]

这使得指定目录中的文件可供导入,我可以从Server.py导入用户。

在完成上述贡献者给出的答案后 - Zorglub29,Tom,Mark,Aaron McMillin,lucasamaral,JoeyZhao,Kjeld Flarup,Procyclinsur,martin.zaenker,tooty44以及调试我面临的问题我发现了一个不同的用例到期我面对这个问题。 因此,在下面添加我的观察结果供任何人参考。

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

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 pytest tests / test_utilities.py来执行用test_utilities.py编写的UT时出现以下错误。

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 '文件夹中有__init__.py文件以及' tests '文件夹,只能通过重新分解代码来摆脱' ImportError '。

stackoverflow链接之后提供了有关Python中循环依赖的更多详细信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM