【问题标题】:How to dynamically import the class?如何动态导入类?
【发布时间】:2021-12-10 10:51:40
【问题描述】:

我有四个文件:main.pyMainClass.pySigClass.pyMyClassC.py。条目是main.py。我在MyClassC中重写了MyClassA的函数function_a,所以我需要在main.pysig属性中设置SigClass,所以MainClass继承了MainClass.py中的MyclassCMyclassA。我的代码如下,没有继承MyClassC的函数function_a

This question explains why the weird class in the middle is used.

我尝试了很多方法,但我只能在main()空间MainClass.pyTempClass实现我的目标,但在MainClass.py空间的__main__做不到。

main() 空间中的TempClass 如何在其他文件中被引用?实在想不出办法。

如何修改代码?或者有没有其他办法?

示例代码如下:

main.py:

from MainClass import SigClass, main

SigClass.sig = "MyClassC"
main()
from MainClass import MainClass

MainClass.function_a()
print(MainClass.property)

MainClass.py:

from time import time
from SigClass import SigClass
import importlib

sig = SigClass.sig


class MyClassA:
    sig = '1'
    property = 'A'

    @classmethod
    def function_a(cls):
        cls.property = 'A'


class MainClass:
    pass


def main():
    module_name = SigClass.sig
    class_name = SigClass.sig
    module_object = importlib.import_module(module_name)
    module_class_object = getattr(module_object, class_name)

    class TempClass(module_class_object, MyClassA):
        pass

    global MainClass

    MainClass = TempClass

SigClass.py

class SigClass:
    sig = 1

MyClassC.py

from MainClass import MyClassA


class MyClassC(MyClassA):
    @classmethod
    def function_a(cls):
        cls.property = 'c'
        pass

【问题讨论】:

  • 为什么你想这样做? 有时需要动态继承,但一般来说,动态编程是一种引入错误的重要方法。如果您可以避免在运行时创建和修改类,您的代码将很多更易于阅读/维护
  • 我真的认为在以后尽可能简要地指定用例是一个好主意。当我第一次阅读它时,我以为您只是想用子类中的一个方法替换一个类中的方法(在这种情况下,除了 define 方法之外,您不需要其他任何东西);然后我以为你正在构建某种动态模型,它必须适应不断变化的第三方数据结构,然后我又读了一遍,对你所说的 __main__ 空间(你只是指模块范围?)
  • MainClass.py 中的__main__ 是什么?我知道什么是模块级范围,我知道 __name__ == "__main__" 是什么,但我不知道(函数?)__main__ 以某种方式存在于该模块中但实际上没有被定义是...
  • @jaried '大量要加载的对象' 如果您编辑您的问题以说出main 实际上应该做什么,以及为什么需要加载这些对象。在没有奇怪的中间类的情况下,在运行时基于一些动态条件实例化一个对象绝对是可能的(例如,只在模块上使用getattr,或者在字典中维护一个手动映射)。这些类什么,你的代码如何决定它需要哪些(以及它用于什么)?
  • 如果您现在有不同的问题,您应该单独发布,而不是试图“重复使用”这个问题。

标签: python class inheritance


【解决方案1】:

感谢@2e0byo 的提示,我认为以下代码最能满足我的需求:

根据SigClass.sig导入MyClassCSigClass.sig也是MainClass最重要的部分。

class BaseClass:
    name = None
    pass


class SigClass(BaseClass):
    name = "SigClass"
    sig = 1


class MyClassA(BaseClass):
    name = "MyClassA"
    property = 'A'
    sig = 'a'

    @classmethod
    def function_a(cls):
        pass


class MyClassC(MyClassA):
    name = "MyClassC"
    property = "C"
    sig = 'c'

    @classmethod
    def function_a(cls):
        pass


class ClassCollections(BaseClass):
    classes: dict = {}

    @classmethod
    def add_class(cls, class_to_add: type(BaseClass)):
        cls.classes[class_to_add.name] = class_to_add


SigClass.sig = "MyClassC"
ClassCollections.add_class(MyClassA)
ClassCollections.add_class(MyClassC)


class MainClass(SigClass, ClassCollections.classes[SigClass.sig], MyClassA):
    pass


print(MainClass.sig)
MyClassC

【讨论】:

    猜你喜欢
    • 2017-12-12
    • 2019-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多