RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1316289
Accepted
Vasyl Kolomiets
Vasyl Kolomiets
Asked:2022-08-11 02:14:44 +0000 UTC2022-08-11 02:14:44 +0000 UTC 2022-08-11 02:14:44 +0000 UTC

工厂的工厂 - 如何

  • 772

在数据处理任务中,一切都是例行公事。我们收到一个包裹(或一封信),阅读文件,处理文件,根据到达的文件集(例如,xlsx 文件)创建所需类型的报告,格式化报告,并将生成的文件发回。对于这样的任务,我构建了一个抽象类:

from pathlib import Path

from abc import ABC, abstractmethod   # , abstractproperty


class IZI_report(ABC):
"""Class for reports."""

def __init__(self,  path_to_files_folder: Path):
    self.path_to_files_folder = path_to_files_folder
    self.response = {             # dict_to_return
        "exit_is_ok": False,
        "exit_message": "",
         # ...
     }

@abstractmethod
def files_reading(self, path_to_files_folder):
    ...

@abstractmethod
def data_processing(self, **pd_files):
    ...

@abstractmethod
def excel_writer(self, path_to_files_folder, client_name, files):
    ...

@abstractmethod
def excel_file_formatting(self, file_to_attach):
    ...

这假设预文件已经在file_to_attach. 但这并不重要。
一切都会好起来的,但是在 Windows 环境中使用本机库格式化 Excel 文件比不依赖于操作系统的“通用”文件快 10 倍。因此,该方法的每个具体实现 excel_file_formatting(self, file_to_attach)对我来说都是这样的:

def excel_file_formatting(self, file_to_attach):

    def o_excel_file_formatting(file_to_attach):
        # используем медленный универсальный модуль
        ...


    def w_excel_file_formatting(file_to_attach):
        # используем быстрый windows-модуль
        ...

   
    return (w_excel_file_formatting if current_os_is_win else o_excel_file_formatting)(file_to_attach)

但在我看来并不漂亮。由于每个特定的方法都重复编写了提供格式化的辅助函数。例如o_header_wrap_and_size或o_search_and_colorise。我认为这个名字清楚地表明了他们的工作。如果它们到处都是重复的,那么就违反了DRY原则。
可以将这些小辅助函数直接包含在抽象类中,但这在某种程度上违反了抽象类中方法的“比例性”。并且制作一个完整的类工厂而不是抽象类方法在某种程度上是可怕和麻烦的。
问题 - 在这种情况下创建方法的标准规则是什么被认为是正确的,“pythonic”?
似乎嵌套类会在这里做,不是吗?
但是,关于嵌套(内部,嵌套) 类被划分。有反对,有赞成。对此有什么建议吗?

python
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    Дмитрий Калинников
    2022-07-14T17:17:06Z2022-07-14T17:17:06Z

    有一种感觉,组合在这里可以提供帮助。你创建一个基类ExcelFormatter,实现WindowsExcelFormatter和GenericExcelFormatter。当然,它们应该提供相同的 API。

    在这种情况下,您通过调用基类的方法从报表类中提取低级格式化逻辑,并在初始化报表时ExcelFormatter设置实例和设置,定义系统。ExcelFormatter

    • 2
  2. Vasyl Kolomiets
    2022-08-18T01:35:22Z2022-08-18T01:35:22Z

    我走的是创建嵌套类的路线,并在__init__.
    我希望这个实现不要太自命不凡。最后,这个解决方案适合我:重复的函数在类中描述,所以它们不需要在每个实现中重写。并且根据操作系统类型创建一个类是明确写出的。所以没有“隐藏”的影响。

    from pathlib import Path
    import os
    import sys
      
    from copy import copy   # , deepcopy
    
    from openpyxl.styles import Color, PatternFill, Font, Border
    import openpyxl as opx
    
    from abc import ABC, abstractmethod   # , abstractproperty
    
    
    import win32com.client
    
    
    class IZI_report(ABC):
        """Class for reports."""
    
        def __init__(self,  path_to_files_folder: Path):
            print('IZI_report(ABC) init')
            self.current_os_is_win = sys.platform in ['win32', 'cygwin'] and os.name == "nt"
            if self.current_os_is_win:
                print('win32com.client')
                import win32com.client
            if self.current_os_is_win:
                self.xlsx_formater = self.Windows_excel_file_formatting()
            else:
                self.xlsx_formater = self.Common_excel_file_formatting()
    
            self.path_to_files_folder = path_to_files_folder
    
            self.response = {           # dict_to_return
                "exit_is_ok": False,
                "exit_message": "",
                "files": dict(),
                'zip_path': None,
            }
    
        @ abstractmethod
        def files_reading(self, path_to_files_folder):
            ...
    
        @ abstractmethod
        def data_processing(self, **pd_files):
            ...
    
        @ abstractmethod
        def excel_writer(self, path_to_files_folder, client_name, files):
            ...
    
        class Windows_excel_file_formatting(ABC):
    
            def search_and_colorise(self, work_sheet, searched_texts_list, color=4):
                """"""
                if type(searched_texts_list) is str:
                    raise Exception('list of str expected!')
                for seached in searched_texts_list:
                    work_sheet.Cells.Find(seached).Interior.ColorIndex = color
    
            def header_wrap_and_size(self, ws, size):
                """"""
                ws.Rows('1:1').WrapText = True
                ws.Columns(ws.Range("A1").CurrentRegion.Columns).ColumnWidth = size
                ws.Rows("1:1").EntireRow.AutoFit()
    
            @ abstractmethod
            def excel_file_formatting(self, file_to_format):
                ...
    
        class Common_excel_file_formatting(ABC):
            """Format xlsx file."""
    
            def search_and_colorise(self, work_sheet, searched_texts_list, color='EE1111'):
                """Renewed."""
                if type(searched_texts_list) is str:
                    raise Exception('list of str expected!')
                # openpx style
                fill_color = PatternFill(start_color=color,
                                         end_color=color,
                                         fill_type='solid')
                for searched in searched_texts_list:
                    for j in range(1, work_sheet.max_column + 1):
                        print(work_sheet.cell(row=1, column=j).value)
                        if work_sheet.cell(row=1, column=j).value:
                            if work_sheet.cell(row=1, column=j).value.find(searched) >= 0:
                                work_sheet.cell(row=1, column=j).fill = fill_color
    
            def header_wrap_and_size(self, ws, size):
                """Renewed."""
                for j in range(1, ws.max_column + 1):
                    ws.cell(row=1, column=j).alignment = \
                        opx.styles.Alignment(
                        horizontal='center',  # 'general',
                        vertical='bottom',
                        text_rotation=0,
                        wrap_text=True,
                        shrink_to_fit=False,
                        indent=0)
                    ws.column_dimensions[opx.utils.cell.get_column_letter(j)].width = size
    
            @ abstractmethod
            def excel_file_formatting(self, file_to_format):
                ...
    

    同时,我会说,这样的实现有点“丑陋”))确实,为了创建一个类,有必要从类内部的父类继承,并明确指示抽象的名称班级。像这样:
    class Windows_excel_file_formatting(IZI_report.Windows_excel_file_formatting)
    总计,它有效,但我想要更优雅的东西。

    创建一个直接从磁盘读取文件的测试类的示例,然后使用抽象类中描述的函数对其进行标记search_and_colorise...

    class Test(IZI_report):
    
        def __init__(self, path: Path):
            super().__init__(path)
            self.SNAPSHOTS_PATTERNS = ["rec", "adj", "rei"]
            self.separators = " _-"
    
        def files_reading(self, path_to_files_folder):
            ...
    
        def data_processing(self, **pd_files):
            ...
    
        def excel_writer(self, path_to_files_folder, client_name, files):
            ...
    
        class Windows_excel_file_formatting(IZI_report.Windows_excel_file_formatting):
    
            def excel_file_formatting(self, file_to_format):
                print('excel_file_formatting')
                Excel = win32com.client.DispatchEx("Excel.Application")
                print(1)
                wb = Excel.Workbooks.Open(os.path.join(os.getcwd(), "sh1.xlsx"))
                print(2)
                ws_rec = wb.Worksheets("Аркуш1")
                print("---- before =====")
                self.search_and_colorise(ws_rec, ("01_", '10_', '20_'))
                wb.Save()
                print(3)
                wb.Close()
                Excel.Application.Quit()
                Excel.Quit()
    
        class Common_excel_file_formatting():
            """Format xlsx file."""
    
            def excel_file_formatting(self, file_to_format):
                wb = opx.load_workbook("sh1.xlsx")
                ws_rec = wb["Sheet01"]
    
    
    path_to = Path("nothng.txt")
    zz = Test(path_to)
    zz.xlsx_formater.excel_file_formatting('ff')
    

    一切正常,但不知何故它并不优雅或其他什么,在创建类的过程中过度消耗资源。
    我会很感激提示!

    • 0

相关问题

  • 是否可以以某种方式自定义 QTabWidget?

  • telebot.anihelper.ApiException 错误

  • Python。检查一个数字是否是 3 的幂。输出 无

  • 解析多个响应

  • 交换两个数组的元素,以便它们的新内容也反转

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    表格填充不起作用

    • 2 个回答
  • Marko Smith

    提示 50/50,有两个,其中一个是正确的

    • 1 个回答
  • Marko Smith

    在 PyQt5 中停止进程

    • 1 个回答
  • Marko Smith

    我的脚本不工作

    • 1 个回答
  • Marko Smith

    在文本文件中写入和读取列表

    • 2 个回答
  • Marko Smith

    如何像屏幕截图中那样并排排列这些块?

    • 1 个回答
  • Marko Smith

    确定文本文件中每一行的字符数

    • 2 个回答
  • Marko Smith

    将接口对象传递给 JAVA 构造函数

    • 1 个回答
  • Marko Smith

    正确更新数据库中的数据

    • 1 个回答
  • Marko Smith

    Python解析不是css

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5