Roh*_*ohi 10 python object-oriented-analysis python-3.x
我目前正在设计一个需要管理某个硬件设置的软件.
硬件设置如下:
系统 - 系统包含两个相同的设备,并具有相对于整个系统的某些功能.
设备 - 每个设备包含两个相同的子设备,并且具有相对于两个子设备的某些功能.
子设备 - 每个子设备有4个可配置实体(通过相同的硬件命令控制 - 因此我不将它们视为子子设备).
我想要实现的目标:
我想通过系统管理器控制所有可配置实体(实体以串行方式计数),这意味着我可以执行以下操作:
system_instance = system_manager_class(some_params)
system_instance.some_func(0) # configure device_manager[0].sub_device_manager[0].entity[0]
system_instance.some_func(5) # configure device_manager[0].sub_device_manager[1].entity[1]
system_instance.some_func(8) # configure device_manager[1].sub_device_manager[1].entity[0]
Run Code Online (Sandbox Code Playgroud)
我想到的是:
我正在考虑创建一个抽象类,它包含所有子设备函数(调用转换函数)并让system_manager,device_manager和sub_device_manager继承它.因此,所有类都将具有相同的函数名称,我将能够通过系统管理器访问它们.围绕这些线的东西:
class abs_sub_device():
@staticmethod
def convert_entity(self):
sub_manager = None
sub_entity_num = None
pass
def set_entity_to_2(entity_num):
sub_manager, sub_manager_entity_num = self.convert_entity(entity_num)
sub_manager.some_func(sub_manager_entity_num)
class system_manager(abs_sub_device):
def __init__(self):
self.device_manager_list = [] # Initiliaze device list
self.device_manager_list.append(device_manager())
self.device_manager_list.append(device_manager())
def convert_entity(self, entity_num):
relevant_device_manager = self.device_manager_list[entity_num // 4]
relevant_entity = entity_num % 4
return relevant_device_manage, relevant_entity
class device_manager(abs_sub_device):
def __init__(self):
self.sub_device_manager_list = [] # Initiliaze sub device list
self.sub_device_manager_list.append(sub_device_manager())
self.sub_device_manager_list.append(sub_device_manager())
def convert_entity(self, entity_num):
relevant_sub_device_manager = self.sub_device_manager_list[entity_num // 4]
relevant_entity = entity_num % 4
return relevant_sub_device_manager, relevant_entity
class sub_device_manager(abs_sub_device):
def __init__(self):
self.entity_list = [0] * 4
def set_entity_to_2(self, entity_num):
self.entity_list[entity_num] = 2
Run Code Online (Sandbox Code Playgroud)
问题 :
在我看来,我试图设计的系统是非常通用的,必须有一个内置的python方式来做到这一点,或者我的整个面向对象看它是错误的.
我真的想知道是否有人有更好的方法来做到这一点.
经过深思熟虑,我认为我找到了一种非常通用的方法来解决这个问题,使用了装饰器,继承和动态函数创建的组合.
主要思想如下:
1)每个层为它自动动态创建所有子层相关函数(在init函数内部,在init函数上使用装饰器)
2)动态创建的每个函数根据一个转换功能(这是abs_container_class的静态功能的实体值转换),并调用具有相同名称的降低层功能(参见make_convert_function_method).
3)这基本上导致所有子层功能在更高级别上实现,零代码重复.
def get_relevant_class_method_list(class_instance):
method_list = [func for func in dir(class_instance) if callable(getattr(class_instance, func)) and not func.startswith("__") and not func.startswith("_")]
return method_list
def make_convert_function_method(name):
def _method(self, entity_num, *args):
sub_manager, sub_manager_entity_num = self._convert_entity(entity_num)
function_to_call = getattr(sub_manager, name)
function_to_call(sub_manager_entity_num, *args)
return _method
def container_class_init_decorator(function_object):
def new_init_function(self, *args):
# Call the init function :
function_object(self, *args)
# Get all relevant methods (Of one sub class is enough)
method_list = get_relevant_class_method_list(self.container_list[0])
# Dynamically create all sub layer functions :
for method_name in method_list:
_method = make_convert_function_method(method_name)
setattr(type(self), method_name, _method)
return new_init_function
class abs_container_class():
@staticmethod
def _convert_entity(self):
sub_manager = None
sub_entity_num = None
pass
class system_manager(abs_container_class):
@container_class_init_decorator
def __init__(self):
self.device_manager_list = [] # Initiliaze device list
self.device_manager_list.append(device_manager())
self.device_manager_list.append(device_manager())
self.container_list = self.device_manager_list
def _convert_entity(self, entity_num):
relevant_device_manager = self.device_manager_list[entity_num // 4]
relevant_entity = entity_num % 4
return relevant_device_manager, relevant_entity
class device_manager(abs_container_class):
@container_class_init_decorator
def __init__(self):
self.sub_device_manager_list = [] # Initiliaze sub device list
self.sub_device_manager_list.append(sub_device_manager())
self.sub_device_manager_list.append(sub_device_manager())
self.container_list = self.sub_device_manager_list
def _convert_entity(self, entity_num):
relevant_sub_device_manager = self.sub_device_manager_list[entity_num // 4]
relevant_entity = entity_num % 4
return relevant_sub_device_manager, relevant_entity
class sub_device_manager():
def __init__(self):
self.entity_list = [0] * 4
def set_entity_to_value(self, entity_num, required_value):
self.entity_list[entity_num] = required_value
print("I set the entity to : {}".format(required_value))
# This is used for auto completion purposes (Using pep convention)
class auto_complete_class(system_manager, device_manager, sub_device_manager):
pass
system_instance = system_manager() # type: auto_complete_class
system_instance.set_entity_to_value(0, 3)
Run Code Online (Sandbox Code Playgroud)
这个解决方案还有一个小问题,自动完成不起作用,因为最高级别的类几乎没有静态实现的功能.为了解决这个问题我做了一点欺骗,我创建了一个从所有层继承的空类,并使用pep约定向IDE声明它是正在创建的实例的类型(#type:auto_complete_class).
| 归档时间: |
|
| 查看次数: |
472 次 |
| 最近记录: |