我似乎无法让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'
答案 0 :(得分:115)
我相信您需要在Models目录中创建一个名为__init__.py
的文件,以便python将其视为模块。
然后你可以这样做:
from Models.user import User
您可以在__init__.py
中包含代码(例如,几个不同类需要的初始化代码)或将其留空。但它一定存在。
答案 1 :(得分:20)
您必须在__init__.py
子文件夹上创建Models
。该文件可能为空。它定义了一个包。
然后你可以这样做:
from Models.user import User
在python教程here中阅读所有相关内容。
还有一篇关于python项目文件组织的文章here。
答案 2 :(得分:12)
导入用户
u = user.User()#error就在这一行
由于上面没有提到__init__,你会发现一个ImportError会让问题更加清晰。
您没有得到一个,因为'user'也是标准库中的现有模块。你的import语句抓住那个并尝试在其中找到User类;那是不存在的,只有这样才能得到错误。
通常一个好主意是让你的导入绝对:
import Server.Models.user
避免这种歧义。实际上,从Python 2.7'导入用户'看起来根本不会与当前模块相关。
如果你真的想要相对导入,你可以在Python 2.5中使用稍微丑陋的语法显式地使用它们:
from .user import User
答案 3 :(得分:9)
当您没有标准包结构时,导入位于父文件夹的模块的正确方法是:
import os, sys
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.dirname(CURRENT_DIR))
(你可以合并最后两行,但这种方式更容易理解)。
此解决方案是跨平台的,并且通用性足以在其他情况下无需修改。
答案 4 :(得分:7)
你错过了__init__.py。从Python教程:
需要__init__.py文件 让Python将目录视为 包含包;这是完成的 防止具有共同的目录 名称,例如字符串,来自 无意中隐藏了有效的模块 稍后在模块搜索中发生 路径。在最简单的情况下, __init__.py只能是一个空文件,但它也可以执行初始化 包的代码或设置 __all__变量,稍后描述。
在Models目录中放入一个名为__init__.py的空文件,所有文件都应该是黄金。
答案 5 :(得分:1)
如何写出参数os.path.dirname
....命令?
import os, sys
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.dirname(CURRENT_DIR))
答案 6 :(得分:0)
我首选的方法是在包含其他模块使用的模块的每个目录上都有__init__.py,并在入口点覆盖sys.path,如下所示:
<owl:DatatypeProperty rdf:about="http://sisinflab.poliba.it/semanticweb/ontologies/architecturalpatterns#extensibilityRate">
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#FunctionalProperty"/>
<rdfs:label xml:lang="en">extensibilityRate</rdfs:label>
<rdfs:range>
<rdfs:Datatype>
<owl:intersectionOf rdf:parseType="Collection">
<rdfs:Datatype>
<owl:onDatatype rdf:resource="http://www.w3.org/2001/XMLSchema#integer"/>
<owl:withRestrictions rdf:parseType="Collection">
<rdf:Description>
<xsd:minInclusive rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">0</xsd:minInclusive>
</rdf:Description>
</owl:withRestrictions>
</rdfs:Datatype>
<rdfs:Datatype>
<owl:onDatatype rdf:resource="http://www.w3.org/2001/XMLSchema#integer"/>
<owl:withRestrictions rdf:parseType="Collection">
<rdf:Description>
<xsd:maxInclusive rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">4</xsd:maxInclusive>
</rdf:Description>
</owl:withRestrictions>
</rdfs:Datatype>
</owl:intersectionOf>
</rdfs:Datatype>
</rdfs:range>
</owl:DatatypeProperty>
这使得指定目录中的文件可供导入,我可以从Server.py中导入用户。
答案 7 :(得分:0)
经过以上这些贡献者给出的答案- 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 ”文件夹和“ tests ”文件夹中都有__init__.py
文件,但仍然可以删除“ ImportError (导入错误”),只需重构代码即可。
下面的stackoverflow链接提供了有关Circular dependency in Python的更多详细信息。