“从模块导入类”从同一模块导入其他类

时间:2020-10-01 09:49:23

标签: 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 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()

我希望仅导入SubClassA,并且在遍历CommonClass的子类时可见,但是似乎也导入SubClassB

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

$ python3 c.py      
I am A
I am B

如何仅导入所需的类?

2 个答案:

答案 0 :(得分:3)

没有仅将SubClassA导入到c.py。可以通过做这件事来测试

x = SubClassB()

x = b.SubClassB()

两者都会导致NameError

问题是,当您import使用文件时,实际上正在运行它,即使使用from x import y

通过在print("I'm from b.py")的末尾添加b.py然后运行c.py可以很容易地看到这一点。

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


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


无论如何,您现在甚至都没有真正使用导入的SubClassA。如果要“允许”某些类仅从外部来源考虑,则可以创建允许的一组类:

from a import CommonClass
from b import SubClassA

allowed_classes = {SubClassA}

if __name__ == "__main__":
    for member in CommonClass.__subclasses__():
        if member in allowed_classes:
            member().do_thing()

仅打印I am A

答案 1 :(得分:0)

from a import CommonClass
from b import SubClassA

if __name__ == "__main__":

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

您可以这样做。