就我而言,在 python 中是否有使用多重继承的替代方法?

Is there an alternative to using multiple inheritance in python in my case?

假设有几个 classes

class Order:
  def create_basic_order(self):
    pass
    # something here

  def create_difficult_order(self):
    pass
    # something here  


class Point:
  def create_full_point(self):
    pass
    # something here

  def create_limited_point(self):
    pass
    # something here

并且客户端以json格式发送带有特定命令的请求。例如 {"command": "create_limited_point"}.

并且服务器应该执行适当的命令。在这种情况下:Point().create_limited_point().

所有命令都不同。 没有“if 构造”的最明显的方法是这样的:

class App(Order, Point):
  pass
  # maybe something here

# Code to handle client request
command = 'create_limited_point'
a = App()
method_to_call = getattr(a, command)
method_to_call()

class应用程序收集了客户端可以使用的所有方法。 这是完成手头任务的好方法吗?

我不确定你的应用是什么,但你是对的,你建议的解决方案很糟糕。如果可以的话,您应该稍微重构一下这段代码。多重继承通常不是一个好主意。

类似的东西可能更适合你。

import abc
from typing import Dict


class EventHandler(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def handle(self):
        pass


class BasicOrderHandler(EventHandler):
    def handle(self):
        pass


class DifficultOrderHandler(EventHandler):
    def handle(self):
        pass


class FullPointHandler(EventHandler):
    def handle(self):
        pass


class LimitedPointHandler(EventHandler):
    def handle(self):
        pass


class App:
    commands_handlers_mapper: Dict[str, EventHandler] = {
        'create_limited_point': LimitedPointHandler,
        'create_full_point': FullPointHandler,
        'create_difficult_order': BasicOrderHandler,
        'create_basic_order': BasicOrderHandler
    }

    def execute_command(self, command: str) -> None:
        handler = self.commands_handlers_mapper[command]
        handler.handle()


command = 'create_limited_point'
a = App()
a.execute_command(command)

将那些 commands 放入常量的奖励积分,这只是一个 class 属性、枚举或只是分配给变量的字符串。

由于App只是作为命名空间使用,所以不需要多重继承的复杂性。直接使用显式的可调用对象命名空间更容易也更灵活。

order = Order()

def hello():
    return 'Hello!'

commands = {
    # arbitrary callable
    'hello': hello,
    # methods of shared object
    'create_basic_order': order.create_basic_order,
    'create_difficult_order': order.create_difficult_order,
    # methods of individual objects
    'create_full_point': Point().create_full_point,
    'create_limited_point': Point().create_limited_point
}

# execute command by name
command = 'create_limited_point'
commands[command]()

当然,可以根据需要将其中的各个部分自动化。

# automatically use name of callable as command name
commands = {
    call.__name__: call
    for call in (
        hello,
        Point().create_full_point, Point().create_limited_point,
    )
}
# add all public methods of an object
for name in dir(order):
    if name.startswith('_'): continue
    commands[name] = getattr(order, name)