【问题标题】:How to build a class into a Python module如何将类构建到 Python 模块中
【发布时间】:2020-02-10 04:50:57
【问题描述】:

我有一个类文件fil1.py,在这个文件中,只有一个类叫做f。我想将这个类文件构建到一个模块中,我尝试过像这样组织我的文件:

foo/
 foo/
    __init__.py
    file1.py # where class resides
 setup.py
 README.md
 LICENSE

__init__.py,我有一句话:

from file1 import f

然后,当我在 pypi 上发布然后安装回我的本地计算机时。当我尝试时:

from foo import f

我收到一条错误消息:

ImportError: cannot import name 'f' from 'foo'

我也试过了

import foo
foo.f

错误信息是:

foo has no attribute f

我不确定如何实现我想要的。

【问题讨论】:

  • 试试这个“from foo.file1 import f”
  • @python_user 我试过了,错误消息是“没有名为 file1 的模块”。而我的最终目标是直接从 foo 导入 f。
  • 原代码能用吗?我的意思是,从 pypi 安装之前的代码。
  • @HuLuViCa 是的,它运作良好。在安装之前,file1 将是包含 f 类的主代码。我可以from file1 import f

标签: python python-module


【解决方案1】:

Python 中没有“类文件”之类的东西。文件是一个模块,模块可能包含零个或多个类、函数或未包含在类或函数中的有效 python 语句(在导入模块时只运行一次)。也就是说,我想你想要:

foo/file1.py:

class f:
[...]

foo/__init__.py:

from foo.file1 import f

那么以下所有内容都是有效的(假设foosys.path 上可用,其中自动将当前工作目录作为第一个条目包含在内):

import foo
import foo.file1
from foo import f
from foo.file1 import f

foo 是一个包(因为它包含__init__.py),其中包含一个名为file1 的模块。或者,您可以在 __init__.py 中使用相对导入:

from .file1 import f

但这可能会变得混乱,并且在大型项目中通常不受欢迎。

【讨论】:

  • 我同意。我的第一个问题是是否有办法绕过相对进口?我想将导入设为绝对导入。第二个问题是如何使导入更干净。因为我只有一门课需要从file1.py 导入。如何使直接导入此类成为可能?喜欢import f。或from foo import f
  • 任何绝对导入(即import foo)必须可以使用sys.path 访问。有关绝对/相对导入的说明,请参阅 PEP328 (python.org/dev/peps/pep-0328)。在包装内使用from foo.bar import baz, bat 是标准的,它一点也不干净或麻烦。它是有意设计的(同样,PEP328)。
【解决方案2】:

为了实现从包 foo 的绝对导入,我所做的是将我的类定义移动到 py.py 中。见Using pip to install single class package without module.pyfile import

root/
 foo/
    __init__.py # where class resides
 setup.py
 README.md
 LICENSE

那我就可以了

from foo import f #f is the class previously in the file1.py

【讨论】:

  • 您可以使用我在回答中解释的方法进行from foo import f。它们都起作用的原因是相同的:__init__.py 的内容在您导入包时被隐式使用,或者from 包的内容。在我的回答中,from foo import f 有效,因为__init__.py 中的代码可以使用名为f 的模块。您已经完成了基本相同的事情,但是使用这种直接在__init__.py 中添加类定义的方法几乎总是会令人不悦。这是不好的做法。不要这样做。
  • 我更新了我的答案以包括使用此包/模块结构进行导入的有效方法。您可能想阅读以下内容:docs.python.org/3/tutorial/modules.html#packages
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-08-02
  • 2015-06-23
  • 2012-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-17
相关资源
最近更新 更多