简体   繁体   English

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

[英]"from module import class" importing other classes from same module

Given the following files:鉴于以下文件:

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()

I would expect only SubClassA is imported, and visible when looping through subclasses of CommonClass , but it seems SubClassB is imported as well.我希望只导入SubClassA ,并且在循环访问CommonClass子类时CommonClass ,但似乎也导入了SubClassB

I am running Python 3.8.5 and this is the output of python3 c.py :我正在运行 Python 3.8.5,这是python3 c.py的输出:

$ python3 c.py      
I am A
I am B

How can I only import the classes I want?我怎样才能只导入我想要的类?

You did import only SubClassA to c.py .你们这样做仅导入SubClassAc.py This can be tested by doing这可以通过做来测试

x = SubClassB()

or或者

x = b.SubClassB()

Both will result in a NameError .两者都会导致NameError

The thing is, that when you import a file, it is actually being ran, even when using from x import y !问题是,当您import文件时,它实际上正在运行,即使使用from x import y

This can be easily seen by adding a print("I'm from b.py") at the end of b.py and then running c.py .这可以通过添加一个很容易地看到print("I'm from b.py")在结束b.py ,然后运行c.py

This makes both SubClassA and SubClassB be subclasses of CommonClass , which you imported.这使得SubClassASubClassB都是您导入的CommonClass子类。 So, while you don't have access to the SubClassB name , it is still a subclass of CommonClass and you can access it from there.因此,虽然您无权访问SubClassB name ,但它仍然是CommonClass的子类,您可以从那里访问它。


In general you don't have to import a module to be able to use its objects.通常,您不必导入模块即可使用其对象。 Importing expands your namespace to include that module so you can create an object directly.导入扩展了您的命名空间以包含该模块,以便您可以直接创建对象。 You can still use this module's objects even without importing it if you acquired them in some other way (like importing a third module which returns objects from the second one).如果您以其他方式获取它们,即使不导入它,您仍然可以使用该模块的对象(例如导入第三个模块,该模块从第二个模块返回对象)。


Anyway right now, you are not really using even the imported SubClassA .无论如何,现在您甚至没有真正使用导入的SubClassA If you want to "allow" certain classes to be considered only from an external source, you can create an allowed set of classes:如果您想“允许”仅从外部来源考虑某些类,您可以创建一组允许的类:

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()

Which only prints I am A只打印I am A

from a import CommonClass
from b import SubClassA

if __name__ == "__main__":

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

You can do this.你可以这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM