我已经开始学习python并编写一个练习应用程序。目录结构如下所示
src
|
--ShutterDeck
|
--Helper
|
--User.py -> class User
--Controller
|
--User.py -> class User
src
目录位于PYTHONPATH
中。在另一个文件中,比如main.py
,我想访问两个User
类。我该怎么做。
我尝试使用以下方法,但失败了:
import cherrypy
from ShutterDeck.Controller import User
from ShutterDeck.Helper import User
class Root:
@cherrypy.expose
def index(self):
return 'Hello World'
u1=User.User()
u2=User.User()
这肯定是模棱两可的。我能想到的另一种(c++的实现方式)是
import cherrypy
from ShutterDeck import Controller
from ShutterDeck import Helper
class Root:
@cherrypy.expose
def index(self):
return 'Hello World'
u1=Controller.User.User()
u2=Helper.User.User()
但是当上面的脚本运行时,它给出以下错误
u1=Controller.User.User()
AttributeError: 'module' object has no attribute 'User'
我不明白为什么会出错?目录ShutterDeck
、Helper
和Controller
中包含__init__.py
。
4条答案
按热度按时间w3nuxt5m1#
您希望导入包
__init__.py
文件中的User
模块,以使它们可用作属性。因此,在
Helper/__init_.py
和Controller/__init__.py
中添加:这使模块成为包的一个属性,现在您可以这样引用它。
或者,您必须完整导入模块本身:
所以请用他们的全名来称呼他们。
另一个选项是使用
as
重命名导入的名称:zaq34kh62#
一种方法是:
你也可以这样做:
dz6r00yl3#
这可能也有帮助(今天遇到类似的问题):
在
ShutterDeck/{Controller,Helper}/__init__.py
中:然后:
5tmbdcev4#
您可以设计
sys.modules
来完成此操作。如果您有两个文件version_file.py,其中包含两个不同模块/项目的版本信息。
导入第一个:
然后处理另一个:
现在有两个导入的模块,
project_a_version_file_mod
和project_b_version_file_mod
。假设两者都有一个attr“version”,你可以得到它们各自的值:project_a_version_file_mod.version
和project_b_version_file_mod.version
。我没有看到任何问题,在这项技术,但会有兴趣听到,如果有人可以指出任何问题。
sys.modules dict的特性和陷阱
注意,根据我的实验,重要的是要知道,如果
importlib.import_module
查看sys.modules
并发现已经有一个键用于要求它添加的下一个模块,它只是忽略了新指令!我觉得这很奇怪,但似乎是这样。因此,如果您在上面的第一个导入操作中没有删除(
del sys.modules['version_file']
),则第二个导入操作将在import_module
上导入失败(无提示),因此在这种情况下,project_b_version_file_mod
实际上也指向版本文件模块project_a_version_file_mod
。类似地,如果在第一个操作之前已经有一个键为“version_file”的条目,则导入操作将不会发生。这就是为什么必须处理这种可能性。
sys.path列表的特性和陷阱
NB 2以上,我建议删除添加到
sys.path
的条目,以便在导入之后导入模块。然后可能会提出这样的异议:“但是假设添加的路径已经存在于sys.path中?“.答案是
sys.path
是list
,而不是set
,所以实际上可以有多个相同的路径条目,这通常是不希望的,但在这种情况下,这使得处理变得相当简单:通过删除添加的路径,您可以保证将sys.path
返回到以前的方式。