【问题标题】:Choose which parent class inherit from in Python在 Python 中选择从哪个父类继承
【发布时间】:2019-12-11 11:47:09
【问题描述】:

我正在努力尝试在创建类时选择要继承的父类而不影响任何子类。

有一个金字塔结构的类,在顶部,我尝试选择从哪里继承:threading.Threadmultiprocessing.Process(使用子类的参数指定它)。

我只在金字塔的第一层创建了一个返回基类的函数,代码在这里:

class ProcessClass(object):
    '''A thread with different inheritance.
    '''
    def __new__(cls, *args, **kwargs):
        thr_type = kwargs.pop("thr_type","threading")
        print("HELLO", thr_type)
        if(thr_type == "threading"):
            new_cls = threading.Thread 
        if(thr_type == "multiprocessing"):
            new_cls = multiprocessing.Process
        instance = super(ProcessClass, cls).__new__(obtain_thread_class(new_cls))
        instance.__init__(*args, **kwargs)
        return instance

def obtain_thread_class(new_cls):
    class BaseClass(new_cls):
        """Class with its methods"""
        def __init__(self, daemon=False, *args, **kwargs):
            # THREADING
            super(BaseClass, self).__init__(*args, **kwargs)
            self.daemon=daemon
        def hello(self):
            print("Hello World")
    return BaseClass

但是现在,当我尝试在子类中继承ProcessClass时,这个会失去他所有的属性,并且无法正确传递参数(我认为这是由于__new__)。

子示例类是:

class ExampleClass(ProcessClass):
    def __init__(self, arg1, arg2, arg3="1", *args, **kwargs):
        self.list_args = [arg1, arg2]
        print("arg3 is", arg3)
        super(ExampleClass, self)
    def hello2(self):
        print("Hello from child!")

有了这个,如果我执行:

a = ExampleClass(thr_type="threading")
print(type(a))

我得到:

HELLO threading
<class '__main__.obtain_thread_class.<locals>.BaseClass'>

但是,我只能打电话给hello(),但不能打电话给hello2()

a.hello()
Hello World

a.hello2()
Traceback (most recent call last):

  File "<ipython-input-11-2505bb83de52>", line 1, in <module>
    a.hello2()

AttributeError: 'BaseClass' object has no attribute 'hello2'

我认为使用__new__ 会破坏儿童的创造。

我也尝试过使用装饰器,并看到了 __metaclasses__ 的一些东西,但在深入这些领域之前,我想知道是否有更简单的东西,因为我不是 python 专家。

此外,我不希望此更改影响我正在运行的任何程序(许多类都继承自 ProcessClass,但目前这只是 threading.Thread)。我正在尝试为整个程序保留此更改unnoticiable

【问题讨论】:

  • 您是否考虑过为不同的流程类型使用组合,而不是使用继承?
  • 这种方法没有任何意义:有一个类ExampleClass,这还不够(如果您希望对象实际上将这些派生类作为它们的类型以便方法查找起作用), ProcessClass 创建的每个object 都有一个单独的BaseClass,这也是错误的。您是在寻求帮助自动生成类或编写工厂函数还是什么?
  • 我试图弄清楚如何简单地决定带有参数的ProcessClass 的父类。 BaseClass 之前在 ProcessClass 内部,但是由于我使用 __new__ 返回了一个新类,因此我将基类中所需的方法和属性分开,并使该基类决定其父类。
  • 我想我会像@JoshuaNixon 所说的那样去作曲

标签: python class inheritance


【解决方案1】:

最后我选择了作曲。没有找到如何在运行时选择继承。但这仍然有效。

class ProcessClass(object):
    '''A thread with different inheritance.
    '''
    def __init__(self, thr_type="multiprocessing", *args, **kwargs):
        if(thr_type == "threading"):
            new_cls = threading.Thread
        if(thr_type == "multiprocessing"):
            new_cls = multiprocessing.Process
        self.thread = new_cls(*args, **kwargs)
    def start(self):
        return self.thread.start()

    def run(self):
        return self.thread.run()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-08
    • 1970-01-01
    • 1970-01-01
    • 2010-09-23
    • 2015-11-16
    • 2019-09-25
    • 2017-03-15
    相关资源
    最近更新 更多