代码之家  ›  专栏  ›  技术社区  ›  toti08

Python:将实例变量传递给类方法

  •  2
  • toti08  · 技术社区  · 7 年前

    我正在使用 xlsxwriter 我创建了一个类,在其中我创建了一个工作簿。然后我添加了2个工作表。 现在我已经编写了一个方法,将数据写入其中一个工作表,但现在我想在两个工作表上都使用它。这是一个简单的例子来解释这种情况:

    import xlsxwriter
    
    class ExcelWorkbook():
        def __init__(self, filename):
            self.wb = xlsxwriter.Workbook(filename)
            self.ws1 = self.wb.add_worksheet('Num')
            self.ws1LineCount = 0
            self.ws2 = self.wb.add_worksheet('Result')
            self.ws2LineCount = 0
    
        def write_data(self, data, title):        
            self.ws1.write_row(self.ws1LineCount, 0, title)
            self.ws1LineCount += 1
            self.ws1.write_row(self.ws1LineCount, 0, data)
            self.ws1LineCount += 1
    
    xlsxWorkbook = ExcelWorkbook('Test2.xlsx')
    numArr = (0.000000520593523979187, 13.123456789, 1.789456, 0.002345, 0.00123, 1)
    titleBar = ('Date', 'quantity', 'Average [m]', 'Standard Dev [m]', 'Test', 'Success')
    xlsxWorkbook.write_data(numArr, titleBar)
    

    write_data 方法,所以我想将工作表作为参数传递,但不幸的是,它并没有那么简单,因为我无法传递实例变量 self.ws1 self.ws2 .

    所以问题是:我该怎么做?

    我想出了一个非常糟糕的解决方案,比如:

    def write_data(self, data, title, instance = 'ws1'):
        if instance == 'ws1':
            instance = self.ws1
            lineCounter = self.ws1LineCount
        elif instance == 'ws2':
            instance = self.ws2
            lineCounter = self.ws2LineCount
    
        instance.write_row(self.ws1LineCount, 0, title)
        lineCounter += 1
        instance.write_row(self.ws1LineCount, 0, data)
        lineCounter += 1
    

    但老实说,我不喜欢它。有没有一个合适的方法来做这件事,或者这是一件完全不合理的事情?

    4 回复  |  直到 7 年前
        1
  •  2
  •   buran    7 年前

    与其使用if块,不如使用 workbook.get_worksheet_by_name() 方法

    def write_data(self, data, title, ws = 'Num'):
        wsheet = self.wb.get_worksheet_by_name(ws)
        wsheet.write_row(self.ws1LineCount, 0, title)
        lineCounter += 1
        wsheet.write_row(self.ws1LineCount, 0, data)
        lineCounter += 1
    

    编辑:也可以使用getattr()函数,例如。

    def write_data(self, data, title, ws = 'ws1'):
        wsheet = getattr(self, ws, self.ws1))
        wsheet.write_row(self.ws1LineCount, 0, title)
        lineCounter += 1
        wsheet.write_row(self.ws1LineCount, 0, data)
        lineCounter += 1
    
        2
  •  1
  •   Felix    7 年前

    from collections import defaultdict
    import xlsxwriter
    
    class ExcelWorkbook():
        def __init__(self, filename):
            self.wb = xlsxwriter.Workbook(filename)
    
            self.ws1 = self.wb.add_worksheet('Num')
            self.ws2 = self.wb.add_worksheet('Result')
            self._line_counts = defaultdict(int)
    
        def write_data(self, ws, data, title):
            self._write_row(ws, title)
            self._write_row(ws, data)
    
        def _write_row(self, ws, content):
            ws.write_row(self._line_counts[ws], 0, content)
            self._line_counts[ws] += 1
    
    xlsxWorkbook = ExcelWorkbook('Test2.xlsx')
    numArr = (0.000000520593523979187, 13.123456789, 1.789456, 0.002345, 0.00123, 1)
    titleBar = ('Date', 'quantity', 'Average [m]', 'Standard Dev [m]', 'Test', 'Success')
    xlsxWorkbook.write_data(xlsxWorkbook.ws1, numArr, titleBar)
    xlsxWorkbook.write_data(xlsxWorkbook.ws2, numArr, titleBar)
    

    利用 defaultdict ,您不需要为每个工作表显式保留行计数变量。这个 write_data 函数接受一个新参数 ws 以便您可以设置应写入的工作表。可以将行写入单独的方法中,以减少代码重复。

    这回答了你的问题吗?

    编辑:

    self ,但您可以非常轻松地解决此问题:

    def write_data(self, data, title, ws=None):
            if ws is None:            
                ws = self.ws1
            self._write_row(ws, title)
            self._write_row(ws, data)
    
        3
  •  1
  •   Cartucho Vasyl    7 年前

    也许你应该考虑多上一节课 ExcelWorksheet ,以便将所有与它们相关的逻辑放入:

    class ExcelWorksheet(object):
        def __init__(self, workbook, name):
            self.wb = workbook
            self.ws = self.wb.add_worksheet(name)
            self.wsLineCount = 0
    
        def write_data(self, data, title):        
            self.ws.write_row(self.wsLineCount, 0, title)
            self.wsLineCount += 1
            self.ws.write_row(self.wsLineCount, 0, data)
            self.wsLineCount += 1
    

    通过这种方式,您可以将代码重构为:

    class ExcelWorkbook(object):
        def __init__(self, filename):
            self.wb = xlsxwriter.Workbook(filename)
            self.ws1 = ExcelWorksheet(self.wb, 'Num')
            self.ws2 = ExcelWorksheet(self.wb, 'Result')
    
    
    xlsxWorkbook = ExcelWorkbook('Test2.xlsx')
    numArr = (0.000000520593523979187, 13.123456789, 1.789456, 0.002345, 0.00123, 1)
    titleBar = ('Date', 'quantity', 'Average [m]', 'Standard Dev [m]', 'Test', 'Success')
    xlsxWorkbook.ws1.write_data(numArr, titleBar)
    xlsxWorkbook.ws2.write_data(numArr, titleBar)
    
        4
  •  -1
  •   Vince    7 年前

    然后vars(self)[“ws1”]类似于self.ws1,vars(self)[“ws2”]类似于self.ws2

    然后只需在write_数据中传递一个关键参数“ws1”或“ws2”。

    def write_data(self, data, title, key='ws1'):
        instance = vars(self)[key]
        lineCounter = vars(self)[key+"LineCount"]
    
        instance.write_row(lineCounter , 0, title)
        lineCounter += 1
        instance.write_row(lineCounter , 0, data)
        lineCounter += 1