【问题标题】:Question about multiple inheritance, dynamic class creating and instantiation关于多继承、动态类创建和实例化的问题
【发布时间】:2020-06-02 12:07:50
【问题描述】:

您好,我有以下情况:

  • 从两个父类继承的特殊类
  • 需要在运行时定义最专业的类,基于我开始从数据库读取数据时获得的一些信息。

我定义了以下代码来处理链中所有类的创建:

class BusinessDocument():
    @staticmethod
    def get_class(doc_type):
        switch = {
            'MasterData': MasterData,
            'Transactional': Transactional
        }
        func = switch.get(doc_type, lambda: "Invalid Noun Type")
        return func()

    def __init__(self, doc_id, location, doc_type):
        self.doc_id = doc_id
        self.location = location
        self.doc_type = doc_type
        pass

    @property
    def get_location(self):
        return self.location

    @property
    def get_doc_id(self):
        return self.doc_id

class MasterData(BusinessDocument):
    def __init__(self, doc_id, location):
        BusinessDocument.__init__(self, doc_id, location, 'MasterData')

class Transactional(BusinessDocument):
    def __init__(self, doc_id, location):
        BusinessDocument.__init__(self, doc_id, location, 'Transactional')


class NounClass():
    @staticmethod
    def get_class(doc_name, doc_type):
        return type(doc_name, (BusinessDocument.get_class(doc_type), 
                           BusinessDocument, ),dict.fromkeys(['doc_id', 'location'])) 

然后在运行时获得 doc_name 并尝试创建一个新类。此时我可能没有所需的参数 doc_idlocation 但我需要对类型进行分类。

invoice_cls = NounClass.get_class('Invoice', 'Transactional')

我收到以下错误:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-10-cb774746875a> in <module>
----> 1 invoice_cls = NounClass.get_class('Invoice', 'Transactional')

<ipython-input-9-aa5e0b316ed1> in get_class(doc_name, doc_type)
     35     @staticmethod
     36     def get_class(doc_name, doc_type):
---> 37         return type(doc_name, (BusinessDocument.get_class(doc_type), 
     38                            BusinessDocument, ),dict.fromkeys(['doc_id', 'location']))

<ipython-input-9-aa5e0b316ed1> in get_class(doc_type)
      7         }
      8         func = switch.get(doc_type, lambda: "Invalid Noun Type")
----> 9         return func()
     10 
     11     def __init__(self, doc_id, location, doc_type):

TypeError: __init__() missing 2 required positional arguments: 'doc_id' and 'location'

我知道原因是因为 __init__() 将在类实例化期间被调用,但我认为该类型只会创建一个新类型而不是立即实例化一个。所以我的问题是,此时是否有办法推迟实例的实例化。

提前感谢您对此提供的任何帮助和提示。

--医学博士。

【问题讨论】:

  • 我在你的问题中没有看到多重继承的例子。我确实看到了两个来自公共基类的单一继承案例。此外,基类可以实现 instance 方法,例如 getClassName(self)return self.__class__.__name__。那么为什么派生类将它们的名称传递给父类呢?我不知道你想解决什么问题。也许您可以更详细地解释一下。

标签: python metaclass python-object


【解决方案1】:

初始化发生在第 9 行:

    return func()

我假设你想返回一个类对象,所以去掉那些括号。

另外 func 有误导,我已将其更改为 cls

def get_class(doc_type):
    switch = {
        'MasterData': MasterData,
        'Transactional': Transactional
    }
    cls = switch.get(doc_type, lambda: "Invalid Noun Type")
    return cls

【讨论】:

  • 修改完成后,它进一步移动并能够在 jupyternote 书中尝试,但是当我将它移动到实际代码中时,当我尝试执行时,类被创建,并且当我尝试通过传递 2 个必需的参数来实例化它时,我得到一个异常,即 '__new__()' 接受 x 个参数,但给出了 y,等等......所以看起来 __new__() 正在某个地方调用不正确的数字参数?我在哪里可以找到那个?
  • @Cracoras 然后更新您的问题。无论如何,我运行invoice_cls(123, 'asdf')没有问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-02
  • 1970-01-01
  • 2017-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多