我正在尝试基于Pandas'ExcelWriter
创建一个文件编写器。我继续像往常一样继续使用Python(3)中的类继承:
import pandas as pd
class Writer(pd.ExcelWriter):
def __init__(self, fname, engine='openpyxl'):
pd.ExcelWriter.__init__(self, fname, engine=engine)
self.newvar = 0
但是,当我尝试使用它时,我无法访问newvar
:
test = Writer('test.xlsx')
test.newvar
返回:
AttributeError: '_XlsxWriter' object has no attribute 'nmax'
当我检查test
的类型时,它会返回:
pandas.io.excel._XlsxWriter
我不明白自己错过了什么,因为我在很多其他情况下都使用过这种继承。任何想法都将不胜感激!
答案 0 :(得分:3)
这是因为pandas.ExcelWriter.__new__
返回的是与自身不同的类(实际上它是abc.ABCMeta
)。根据文件路径的扩展名和使用的引擎选择类 - 当您检查新创建的实例的类型时,您可以观察到该类。这意味着调用返回的任何类的__init__
方法。您可以将ExcelWriter
视为每种格式和引擎的特定编写器的某种代理(尽管它也定义了这样的编写者必须提供的API)。
为了使您的作家可用(对于给定的引擎),您需要register它。
但在您可以这样做之前,您需要按照help(pandas.ExcelWriter)
找到的说明进行兼容。为了完整起见,我在这里引用它们:
# Defining an ExcelWriter implementation (see abstract methods for more...)
# - Mandatory
# - ``write_cells(self, cells, sheet_name=None, startrow=0, startcol=0)``
# --> called to write additional DataFrames to disk
# - ``supported_extensions`` (tuple of supported extensions), used to
# check that engine supports the given extension.
# - ``engine`` - string that gives the engine name. Necessary to
# instantiate class directly and bypass ``ExcelWriterMeta`` engine
# lookup.
# - ``save(self)`` --> called to save file to disk
# - Mostly mandatory (i.e. should at least exist)
# - book, cur_sheet, path
# - Optional:
# - ``__init__(self, path, engine=None, **kwargs)`` --> always called
# with path as first argument.
因此,我们可以扩展你的课程:
class Writer(pd.ExcelWriter):
engine = 'openpyxl'
supported_extensions = ('xlsx',)
def write_cells(self, cells, sheet_name=None, startrow=0, startcol=0):
# Implement something useful here.
pass
def save(self):
# Implement something useful here.
pass
def __init__(self, fname, engine='openpyxl', **kwargs):
super().__init__(self, fname, engine=engine, **kwargs)
现在您可以使用pd.io.excel.register_writer(Writer)
注册编写器。但是您需要确保您指定的引擎与openpyxl
版本匹配。您可以查看特定作者的选择过程here;可以通过print(pd.io.excel._writers)
检查当前为每个版本注册的作者。
作为旁注:你也可以将一个已经可用的特定作者子类化,并重用他们的write_cells
和save
方法(但是在这种情况下你也需要注册你的作者) ):