Python 3.5.2:导入一个在子目录中导入另一个类的类

时间:2016-12-19 01:57:09

标签: python class module python-import

我是stackoverflow和Python的新手,很抱歉这些错误。

我的game.py位于此项目目录中。

我有两个课程,CardClass&类子目录中的CardDeckClass。

CardDeckClass使用CardClass。

/project/game.py
/project/classes/CardClass.py
/project/classes/CardDeckClass.py

我无法将CardDeckClass导入game.py

到目前为止,我已经尝试过这个:

*CardClass.py*
class CardClass:
    ##functionality for CardClass

*CardDeckClass.py*
from random import shuffle
from CardClass import CardClass
class CardDeckClass:
    ##functionality for CardDeckClass

*game.py*
from classes.CardDeckClass import CardDeckClass

testDeck = CardDeckClass()
print("Amount of cards in deck: ", testDeck.getCardCount())

上面给出了CardDeckClass.py第二行的错误:from CardClass import CardClass

ImportError:没有名为' CardClass'

的模块

有关如何解决此问题的任何提示或想法?谢谢!

2 个答案:

答案 0 :(得分:2)

虽然DYZ的回答有效,但我认为它会给你非常糟糕的建议。如果将classes文件夹添加到Python模块搜索路径,您现在可以通过两种不同的方式查找CardClassCardDeckClass模块。您可以直接通过顶级名称(例如import CardClass)或classes包裹(import classes.CardClass)获取。

这种歧义是不好的,因为Python不会意识到这两个不同的名称应该引用相同的东西。相反,你将获得所有内容的两个副本,这可能非常令人困惑。例如,isinstance(CardClass.CardClass(), classes.CardClass.CardClass)将为False

相反,您应该在CardDeckClass.py中修复导入以正确导入CardClass。有两种方法可以做到,你想要的是风格问题(没有一个正确的选择)。除模块名称外,您可以使用绝对导入,命名包:

from classes.CardClass import CardClass

或者您可以使用显式相对导入

from .CardClass import CardClass

注意模块名称开头的点,它告诉Python开始在当前包中搜索。

您可能没有意识到将CardClass.pyCardDeckClass.py文件放在正在为其创建包的文件夹中。在旧版本的Python(在Python 3.3之前)中,您需要将一个名为__init__.py的文件添加到文件夹中,然后才能作为包使用。这已经不再需要了(因为有些模糊不清的原因,请参阅PEP 420及其引用的PEP)。仍然建议添加__init__.py文件,因为您通常不需要将您的包作为"命名空间包" (如果你不知道命名空间包是什么,你就不需要了。)

最后一个建议:您的模块命名方案表明您创建的每个模块中只有一个类。这在Python中往往很糟糕。与Java等其他语言不同,Python模块中包含许多类,函数和其他内容是很正常的。过多地分割代码会使导入变得比它们需要的复杂得多。在这种情况下,几乎可以肯定地组合CardClassCardDeckClass模块,因为它们处理密切相关的对象。将它们组合到game.py文件中是最有意义的,尽管单独的cards模块也可以。这里几乎肯定不需要包装。

答案 1 :(得分:0)

通常子目录classes不在默认导入路径上。如果您希望从非标准子目录导入您的类,则必须将其添加到路径中:

import sys
sys.path.append("./classes")