Python。如何优化类集?

2024-09-26 22:49:44 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下几点:

class DepartmentsSet(ComplexModel):
    __namespace__ = MODELS_NS

    service_difference_set = Iterable(Department)
    db_difference_set = Iterable(Department)
    intersection_difference_set = Iterable(Department)

    def __init__(self, service_diff, db_diff, intersection):
        self.service_difference_set = _convert_to_departments(service_diff)
        self.db_difference_set = _convert_to_departments(db_diff)
        self.intersection_set = _convert_to_departments(intersection)


def _convert_to_departments(operation_set):
    departments = []
    for item in operation_set:
        department = dict(item)
        departments.append(Department(
            name=department.get('name'),
            external_id=department.get('external_id')
        ))


class EmployeesSet(ComplexModel):
    __namespace__ = MODELS_NS

    service_difference_set = Iterable(Employee)
    db_difference_set = Iterable(Employee)
    intersection_set = Iterable(Employee)

    def __init__(self, service_diff, db_diff, intersection):
        self.service_difference_set = _convert_to_employees(service_diff)
        self.db_difference_set = _convert_to_employees(db_diff)
        self.intersection_set = _convert_to_employees(intersection)


def _convert_to_employees(operation_set):
    employees = []
    for item in operation_set:
        employee = dict(item)
        dep = employee.get('department')
        employees.append(Employee(
            name=employee.get('name'),
            post=employee.get('post'),
            department=(dep.name if isinstance(dep, CompanyDepartment) else u''),
            contact_info=employee.get('contact_info'),
            external_id=employee.get('external_id')))
    return employees

我有两个问题:

  1. 如您所见,我的类DepartmentsSetEmployeesSet都有相似的结构。它们之间唯一的区别是它们的集合由_convert_to_departments_convert_to_employees组成。 我意识到我的解决方案不好。这个案子的最佳做法是什么?

  2. 有没有办法把函数_convert_to_departments_convert_to_employees统一成一个通用函数?

*我不能为DepartmentsSet和EmployeesSet创建单个类,因为这些类将是我的SOAP服务的类型。你知道吗


Tags: toselfconvertdbgetserviceemployeediff
1条回答
网友
1楼 · 发布于 2024-09-26 22:49:44

解决您的直接问题很简单—将通用代码和变量移到一个超类中,并从中继承EmployeeSet和DepartmentSet,如下所示:

class CommonModel(ComplexModel):

    def get_items(self, operation_set):
        items = [dict(x) for x in operation_set]
        return items

    # important: put COMMON methods, variables etc. here 

class DepartmentsSet(CommonModel):

    ...
    def _convert(self, operation_set):
        items = self.get_items(operation_set)
        for item in items:
            ... # convert to departments

class EmployeeSet(CommonModel):

    ...
    def _convert(self, operation_set):
        items = self.get_items(operation_set)
        for item in items:
            ... # convert to employees

然而,从策略上说,我觉得这并不是一个好的设计,如果真的是“它们之间的唯一区别是它们的集合由…组成”,那么DepartmentSetEmployeeSet真的是一回事吗?你不能把它变成一个有两个转换方法的类吗?你知道吗

不过,这仍然不是很好的设计—您将集合和类中的特定对象混为一谈。这确实违反了单一责任原则。将EmployeeDepartmentCommonModel作为一个类,并简单地将它们的实例放在列表中。如果您真的,真的需要在某个地方进行转换,请提供单个对象转换方法,然后您可以执行以下操作:

[x.convert() for x in list_of_model_instances]

..甚至不用费心去检查x的类(这是duck类型)。你知道吗

我仍然不认为你真的这样做了,它应该是一些其他类或函数,可以采取一个实例CommonModel的输入和做任何它想用它。如果您真的需要进行详细的转换,为什么不创建一个Converter类,它可以接受许多输入实例并输出所需的任何内容?(遵循单一责任原则)

顺便说一句,如果这样做,可以使ComplexModel成为抽象基类或从中继承,如下所示:

class AbstractItemCheckpoint(object):
    __metaclass__ = ABCMeta

    '''Abstract item checkpoint, derive concrete item checkpoints that verify if a item (Subsystem, Component,
       etc.) is eligible for creating a Task for it.'''

    @abstractmethod
    def convert(self):
        '''
        Ensure that model inheriting from AbstractItemCheckpoint has convert method.
        '''
        pass

这可以确保像EmployeeDepartment这样的任何类都必须有convert方法,从而使提交到Converter实例更安全。你知道吗

相关问题 更多 >

    热门问题