问题描述
假设有几个班级
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()
App类收集客户端可以使用的所有方法。 这是完成手头任务的好方法吗?
解决方法
我不确定您的应用程序是什么,但是您说的对,您建议的解决方案太糟糕了。如果可以的话,您可能应该重构一下此代码。多重继承通常不是一个好主意。
类似的方法可能更适合您。
syntax error: unexpected literal "text",expecting method or interface name
将这些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)
放入常量的奖励点,常量只是一个类属性,枚举或只是分配给变量的字符串。
由于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)