【问题标题】:Conditional parameters while using factory pattern使用工厂模式时的条件参数
【发布时间】:2019-12-19 02:55:11
【问题描述】:

我使用老式函数来处理工资单,但现在我将其转移到具有更多功能的网络应用程序,例如工资单处理中的可调整设置。

目前正在阅读有关设计模式的信息,并决定尝试在我的一个项目模块中实现工厂模式,尽管我有点卡住了。目标是将条件参数应用于类属性。

要了解我的旧函数的外观,只需使用 pandas read_excel() 方法将 excel 文件转换为数据框:

def read_excel_files():
    df_stylist_analysis = pd.read_excel(
        Reports.objects.latest('stylist_analysis').stylist_analysis.path,
        sheet_name=0, header=None, skiprows=4)
    df_tips = pd.read_excel(
        Reports.objects.latest('tips_by_employee').tips_by_employee.path,
        sheet_name=0, header=None, skiprows=0)
    df_hours1 = pd.read_excel(
        Reports.objects.latest('hours_week_1').hours_week_1.path,
        header=None, skiprows=5)
    df_hours2 = pd.read_excel(
        Reports.objects.latest('hours_week_2').hours_week_2.path,
        header=None, skiprows=5)
    df_retention = pd.read_excel(
        Reports.objects.latest('client_retention').client_retention.path,
        sheet_name=0, header=None, skiprows=8)
    df_efficiency = pd.read_excel(
        Reports.objects.latest('employee_service_efficiency').employee_service_efficiency.path,
        sheet_name=0, header=None, skiprows=5)
    return df_stylist_analysis, df_tips, df_hours1, df_hours2, df_retention, df_efficiency

如您所见,每个文件中跳过的行数不同。

目前我正在尝试实现一个我编写的 Excel 工厂来代替该函数,以便它可以处理多种 Excel 文件类型:

class XLSDataExtractor:
    def __init__(self, filepath, rows):
        self.data = pd.read_excel(filepath, sheet_name=0, header=None, skiprows=rows)

    @property
    def parsed_data(self):
        return self.data


class XLSXDataExtractor:
    def __init__(self, filepath, rows):
        self.data = pd.read_excel(filepath, sheet_name=0, header=None, skiprows=rows)

    @property
    def parsed_data(self):
        return self.data


def data_extraction_factory(filepath):
    if filepath.endswith('xls'):
        extractor = XLSDataExtractor
    elif filepath.endswith('xlsx'):
        extractor = XLSXDataExtractor
    else:
        raise ValueError(f'Cannot open {filepath}')
    return extractor(filepath)


def extract_data_from(filepath):
    factory_obj = None
    try:
        factory_obj = data_extraction_factory(filepath)
    except ValueError as e:
        print(e)
    return factory_obj


def rows():
    #  if file name == human1 and filepath.endswith('xls') return 4
    #  if file name == human1 and filepath.endswith('xlsx') return 1

如您所见,我需要将rows 作为参数传递给类属性(我认为)。我该如何实施?我在通过这部分时有点挣扎。

【问题讨论】:

    标签: python django python-3.x algorithm design-patterns


    【解决方案1】:

    大概可以这样写:

    def data_extraction_factory(filepath, rows=0):
        if filepath.endswith('xls'):
            extractor = XLSDataExtractor
        elif filepath.endswith('xlsx'):
            extractor = XLSXDataExtractor
        else:
            raise ValueError(f'Cannot open {filepath}')
        return extractor(filepath, rows)
    
    
    def extract_data_from(filepath, rows=0):
        factory_obj = None
        try:
            factory_obj = data_extraction_factory(filepath, rows)
        except ValueError as e:
            print(e)
        return factory_obj

    我在这里发送rows 作为关键字参数。所以你可以调用data_extraction_factoryextract_data_from,带或不带rows参数。

    还有:

    我需要将行作为参数传递给类属性(我认为)

    那不是真的。它们是对象属性,因为您通过 __init__ 函数传递它们。意味着当这些类的对象被启动时,比如file_object=XLSXDataExtractor(...),然后__init__函数被调用,所以你需要传递行的值。


    根据 OP 的评论更新

    def data_extraction_factory(filepath, **kwargs):
        if filepath.endswith('xls'):
            extractor = XLSDataExtractor
        elif filepath.endswith('xlsx'):
            extractor = XLSXDataExtractor
        else:
            raise ValueError(f'Cannot open {filepath}')
        return extractor(filepath, **kwargs)
    
    
    def extract_data_from(filepath, **kwargs):
        factory_obj = None
        try:
            factory_obj = data_extraction_factory(filepath, **kwargs)
        except ValueError as e:
            print(e)
        return factory_obj

    【讨论】:

    • 我喜欢在这里使用 kwargs 的想法。我没有意识到,如果您将 kwarg 设置为 =0,它就不需要参数。我不高兴的一件事是不得不到处写rows。感觉好像没有遵循DRY原则。
    • 另一个想法是使用**kwargs,你可以将任何值作为kwargs传递。示例用法extract_data_from('/abc.xls', rows=12)。请查看更新后的答案
    • 是的,这感觉好多了,并且具有灵活性。我要去玩一玩,看看我怎样才能让它更好地工作。
    猜你喜欢
    • 2013-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多