Python模块与类的区别

3
我有以下目录结构:
ican/
  __init__.py
  haz/
    __init__.py
    apple.py
    grape/
      __init.py
      grape.py

假设我们有两个文件,分别是 apple.pygrape.py ,它们都定义了水果类(fruit class)。现在,在另一个测试文件中,我想通过以下方式之一来加载一个水果类: myapple = ican.haz.apple() 或者 mygrape = ican.haz.grape()

那正确的目录结构和导入结构应该是什么样的呢?我曾试过这样的写法:import ican.haz as icanhaz ,然后调用 myapple = icanhaz.apple() 。我希望把所有的类都放在同一个位置,并通过 ican.haz.<class> 这样的方式来加载它们。


值得指出的是,在Python中,你并不需要将每个类都放在自己的模块中(就像在Java中通常要求的那样)。如果你的AppleGrape类足够简单,你可能希望将它们的代码放在同一个文件中(比如ican/has.py),这样可以省去很多子包的麻烦。 - Blckknght
2个回答

1
你混淆了两个概念。Python中的“模块”是包含可以被导入的Python代码的文件。Python中的“类”是可以在模块中定义的东西。
在你的例子中,apple和grape是模块。你不能像这样调用一个模块:apple(),这是不允许的。你需要导入模块中包含的类。
假设apple.py中定义了一个GetApple类。所以apple.py看起来像这样:
class GetApple(object):
    def __init__(self):
        print("I have an apple!")

模块也可以有函数,因此您可以拥有一个GetApple 函数:

def GetApple():
    print("I have an apple!")

模块也可以拥有变量。它们可以拥有任意数量的变量、类和函数。你可以单独地导入它们(例如使用 from apple import GetApple),或者导入模块并从模块中访问它们(import apple)。但你不能导入并调用一个模块(至少没有合理的方式),只能调用其中的函数或类。

对于你的目录结构,你可以使用以下任何一种方法来运行它:

>>> from ican.haz.apple import GetApple
>>> GetApple()
I have an apple!

>>> from ican.haz import apple
>>> apple.GetApple()
I have an apple!

>>> import ican.haz.apple
>>> ican.haz.apple.GetApple()
I have an apple!

根据你的__init__.py文件,可能还会有:

>>> import ican.haz
>>> ican.haz.apple.GetApple()
I have an apple!

>>> import ican
>>> ican.haz.apple.GetApple()
I have an apple!

对于grape.py,假设有相应的类,可以使用以下代码:
>>> from ican.haz.grape.grape import GetGrape
>>> GetGrape()
I have a grape!

0
为了保持一致,要么
a) 在一个带有init的apple文件夹中,将apple.py放在更低的一级目录中,或者
b) 将grape.py放在更高的一级目录中,而不是它自己的grape文件夹中。
然后你的导入将是from ican.haz.apple import Apple和from ican.haz.grape import Grape(对于选项a);或者from ican.haz import apple, grape(对于选项b)。
为了获得你想要的结构,请选择选项b并修改haz下的init。

haz/__init__.py:

from .apple import Apple
from .grape import Grape

__all__ = ['Apple', 'Grape']

你可以这样导入它:import ican.haz.*(虽然被认为是不好的风格)。这会对模块和类名进行混淆(现在已经修正了类名,所以不再有问题)。最好使用以下选项a或b中的一行。

顺便说一下,根据你当前的结构,导入应该是:

from ican.haz import apple
from ican.haz.grape import Grape

a = apple.Apple()
g = Grape()

当我尝试导入apple时,出现了TypeError: 'module' object is not callable的错误。然而,如果我使用from ican.haz.apple import apple as Apple,那么我就可以创建a = Apple()。为什么这样做可以,但你的方法不行呢? - drjrm3
因为你的类Apple在文件(模块)apple中。 - aneroid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接