Python 使自定义类xlsxwriter友好

Python 使自定义类xlsxwriter友好,python,oop,pandas,xlsxwriter,Python,Oop,Pandas,Xlsxwriter,我正在用熊猫写一些数据分析管道。我一直在使用的dataframes中的一列由自定义编写类的对象组成,每个类都用一个字符串初始化,从中我用正则表达式读取各种信息并存储在对象的属性中。子类结构类似于实现生命树的方式,例如老虎是猫的一个子类,猫是动物的一个子类,通常(但不总是)具有相同超类的动物将共享方法。它也有一些有用的方法,我可以用来计算。For str和repr方法返回用于初始化它的字符串,如下所示: class Animal(object): def __init__(self, n

我正在用熊猫写一些数据分析管道。我一直在使用的dataframes中的一列由自定义编写类的对象组成,每个类都用一个字符串初始化,从中我用正则表达式读取各种信息并存储在对象的属性中。子类结构类似于实现生命树的方式,例如老虎是猫的一个子类,猫是动物的一个子类,通常(但不总是)具有相同超类的动物将共享方法。它也有一些有用的方法,我可以用来计算。For str和repr方法返回用于初始化它的字符串,如下所示:

class Animal(object):

    def __init__(self, name):
        self.name = name
        self.group = self.__class__.__name__

    def __repr__(self):
        return self.name.__repr__()

    def __str__(self):
        return self.name.__str__()
我正在使用这段代码将数据帧字典写入excel电子表格:

        with pd.ExcelWriter(saveas) as writer:
            for key, val in dictionary.items():
                print key
                write_index = not val.data_frame.index.is_integer()
                val.to_excel(writer, sheet_name=key, index=write_index)
            writer.save()
这意味着当我想查看数据帧时,我会看到一个字符串。在包含这些对象的数据框上使用to_csv方法没有问题,但是当我使用pandas数据框的to_excel方法时,我得到以下错误:

  File "C:\Users\Mike\Anaconda\lib\site-packages\xlsxwriter\worksheet.py", line 406, in write
    f = float(token)

TypeError: float() argument must be a string or a number
因此,我在sheetwork.py中找到了这段代码,出现问题的行如下所示:

    try:
        f = float(token) ##THIS IS WHERE THE CODE FAILS
        if not self._isnan(f) and not self._isinf(f):
            return self.write_number(row, col, f, *args[1:])
    except ValueError:
        pass

    # Finally try string.
    try:
        str(token)
        return self.write_string(row, col, *args)
    except ValueError:
        raise TypeError("Unsupported type %s in write()" % type(token))
我在上面的代码中添加了一条注释,以显示故障发生的位置。我的对象没有float方法,所以它们抛出的不是ValueError,而是TypeErrors。从上面的代码可以清楚地看出,如果我们可以传递到第二个try语句,那么编写工作将开始,因为我的类有一个str方法。因此,我给我的自定义类提供了一个float方法,该方法返回一个ValueError,以便触发except子句

然而,xlsx-writer还有更多的问题,一些类似的问题与我的类中缺少某些方法有关,我在每种情况下都添加了这些方法。但是,这只会延迟问题的出现:

  File "C:\Users\Mike\Anaconda\lib\site-packages\xlsxwriter\sharedstrings.py", line 95, in _write_si
    string = re.sub('(_x[0-9a-fA-F]{4}_)', r'_x005F\1', string)
现在,我看代码的问题是,一旦字符串写入工作表,xlsxwriter就会运行一些函数,从写入的文件中获取所有字符串。问题似乎是,一旦工作表被写入writer.save,所有内容都被无误地传递,xlsxwriter就会假定被写入的字符串一直都是字符串,并像对待字符串一样对待它们,而不是像以前那样将它们封装在str函数中


现在,我可以去修改有问题的代码,但我不想在xlsxwriter的更新中处理这些问题。我可以简单地让我的类从str继承,但考虑到我实际上不想使用几乎所有的string方法,这似乎是不符合语法的。最后,我可以通过将这个子类中的所有内容都转换回字符串来清理我的数据帧,但这意味着我必须重写我使用的很多东西,这取决于能否使用dataframe.to_excel方法。在这个类中,我可以做些什么来避免继承str的所有内容吗?

最简单的方法可能就是实现自己的引擎来使用

from pandas import io
class MyXLSWriter(io.excel.xlsx.writer):
     def write_cells(self, cells,*args,**kwargs):
         for cell in cells:
             if isinstance(cell.val,(MyCustomClass1,MyCustomClassN)):
                cell.val = str(cell.val) #or some other representaion...
         io.excel.xlsx.writer.write_cells(self,cells,*args,**kwargs)

my_df.to_excell(fname,engine=MyXLSWriter)

我想至少。。。我完全没有测试它…

如果您使用的是ipython,请尝试使用%debug查看有问题的令牌是什么。有问题的令牌是我在文章中讨论过的类的成员。您确定令牌是什么吗?如果是这样的话,floattoken似乎不会出现…是的。我敢肯定。也许我在文章中不清楚,但当我向类中添加一个引发ValueError的float方法时,该错误消失了。也许我没有清楚地表达我的问题。我已经做了。啊,好的。没问题。我想我可能会把这件事告诉那些在xlsxwriter上工作的人,甚至可能自己也在做,如果他们允许我,这将是我的第一个开源贡献!。看起来这样的事情应该不会出错。@MTrenfield作为xlsxwriter人员/人员,我认为您应该尝试使用当前的Pandas或xlsxwriter API来解决这个问题。在我看来,一个类似于乔兰的解决方案应该是可行的。我不希望扩展XlsxWriter以支持编写任意对象类型。