我有一个包含多个子文件夹的项目,其中大多数是Python包。其中一个包含一个名为BaseStep的抽象类(使用abc
模块创建),它在运行时使用:for subclass in cls.__subclasses__(): ...
查找自身的子类。 BaseStep
位于pipeline
目录中,位于名为base_step.py
的python文件中,因此可以通过pipeline.base_step.BaseStep
进行访问。
此包看起来像:
pipeline/
__init__.py
base_step.py
在另一个Python包中,我想创建一些如何使用BaseStep的示例。这个包名为examples
,我有一个名为sample_step.py
的python文件。在sample_step.py
内,我创建了一个扩展名为BaseStep
的{{1}}类的类。因此,可以通过SampleStep
来访问它。
此包看起来像:
examples.sample_step.SampleStep
但是,当我尝试在运行时访问examples/
__init__.py
sample_step.py
时,我看不到__subclasses__()
列为其中之一。
SampleStep
显示为SampleStep
的子类的唯一方法是,BaseStep
目录的__init__.py
包含pipeline
的导入:< / p>
SampleStep
为什么会这样?为什么我必须在管道包中导入我的示例步骤?为什么不能from examples.sample_step import SampleStep
识别其他包中的子类?任何理解继承和导入的帮助都将深受赞赏。
修改
感谢您的评论。从评论中,我意识到我没有解释如何导入SampleStep,并删除了我对评论的一些回复。
BaseStep
模块实际上是这样的:
examples
在 init .py中,我有examples/
__init__.py
runner.py
sample_step.py
。然后我调用from examples.sample_step import SampleStep
,它通过调用runner.py
中查看其子类的函数来实例化SampleStep
。至少这是它尝试做的事情 - 它失败了,因为BaseStep
没有意识到BaseStep
是一个子类。
@Blckknght说&#34;你可以从任何地方导入模块(只要#34;任何地方&#34;自己加载)&#34;。因此,更具体的问题是:为什么在运行时SampleStep
内SampleStep
导入examples/__init__.py
并BaseStep
才能识别出它是一个子类?
答案 0 :(得分:3)
Python是一种动态语言。像类定义这样的东西在技术上发生在运行时,而不是像C和Java等其他语言中的早期编译时间。这意味着在导入"babel": "^6.5.2",
"babel-plugin-transform-es2015-destructuring": "^6.9.0",
"babel-plugin-transform-object-rest-spread": "^6.8.0",
"babel-preset-es2015": "^6.9.0",
"babel-preset-react": "^6.11.1",
模块并运行其sample_step
类的定义之前,就Python解释器而言,该类并不存在。
您可以从任何地方导入模块(只要&#34;任何地方&#34;都会自行加载)。只需要加载一次,子类就会显示在SampleStep
列表中。
答案 1 :(得分:2)
SampleStep
子类不存在,直到导入文件为止。