Python &引用;“来自模块导入类”;从同一模块导入其他类

Python &引用;“来自模块导入类”;从同一模块导入其他类,python,python-3.x,python-import,Python,Python 3.x,Python Import,给定以下文件: a.py ----- class CommonClass(object): def do_thing(self): pass b.py ----- from a import CommonClass class SubClassA(CommonClass): def do_thing(self): print("I am A") class SubClassB(CommonClass): def d

给定以下文件:

a.py
-----
class CommonClass(object):
    def do_thing(self):
        pass

b.py
-----
from a import CommonClass

class SubClassA(CommonClass):
    def do_thing(self):
        print("I am A")

class SubClassB(CommonClass):
    def do_thing(self):
        print("I am B")

c.py
-----
from a import CommonClass
from b import SubClassA

if __name__ == "__main__":
    for member in CommonClass.__subclasses__():
        member().do_thing()
我希望只有
子类
被导入,并且在
CommonClass
的子类中循环时可见,但似乎
子类b
也被导入

我正在运行python3.8.5,这是python3 c.py的输出:

$ python3 c.py      
I am A
I am B

我怎样才能只导入我想要的类呢?

您只导入了
子类
c.py
。这可以通过以下步骤进行测试

x = SubClassB()

两者都将导致
名称错误

问题是,当您
导入
一个文件时,它实际上正在运行,即使在使用来自x import y的
时也是如此

这可以通过在
b.py
的末尾添加
print(“我来自b.py”)
然后运行
c.py
很容易看出

这使得
子类A
子类B
都是导入的
CommonClass
的子类。因此,虽然您无法访问
子类b
名称,但它仍然是
CommonClass
的子类,您可以从那里访问它


通常,不必导入模块就可以使用其对象。导入将扩展名称空间以包含该模块,以便可以直接创建对象。如果您以其他方式获取了此模块的对象(例如导入第三个模块,从第二个模块返回对象),则即使不导入,也可以使用此模块的对象


不管怎样,现在您甚至都没有真正使用导入的
子类
。如果要“允许”某些类仅从外部源考虑,可以创建一组允许的类:

来自导入类的

从b导入子类a
允许的_类={subassa}
如果名称=“\uuuuu main\uuuuuuuu”:
对于CommonClass中的成员。\uuuu子类\uuuuu():
如果成员在允许的_类中:
成员().做某事()
它只打印
我是一个

from a import CommonClass
from b import SubClassA

if __name__ == "__main__":

    h = CommonClass.__subclasses__()[0]()
    h.do_thing()

您可以这样做。

\uuuuu子类\uuuuuuu()
返回从基类继承的所有类,这就是为什么您会同时获得两个outputshank,是否有任何方法可以避免这种行为?出于我的特殊目的,遍历子类很容易,但我想明确指定要导入的子类。这应该可以做到!我希望避免多次输入允许的类,但我认为这是最接近的。
from a import CommonClass
from b import SubClassA

if __name__ == "__main__":

    h = CommonClass.__subclasses__()[0]()
    h.do_thing()