用模块扩展 python class

Extending python class with module


我想用 matplotlib 中的 pyplot 模块扩展我的 python class:

import matplotlib.pyplot as plt

class MyClass(object, plt):
    pass

这不起作用:

TypeError: Error when calling the metaclass bases
metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

我找到了 this 个问题,但实际上,它并没有真正帮助我解决问题。我用

搜索
>>> type(matplotlib)
>>> type(matplotlib.pyplot)

等对于 classes,但我只得到模块。 API 文档也没有说明任何关于 class 的内容。那么,我做错了什么?我对 python 还是很陌生...

提前致谢!
-ju-

你得到的错误的性质仅仅是因为你不能让 class 从 "object" 和 matplotlib.pyplot 继承 - 但是他们,pyplot 是 module - 即:"ModuleType" class 的实例 - 尝试通过继承来扩充它是没有意义的。

您可以使用简单的属性分配来扩充 pyplot:

import matplotlib.pyplot

def my_new_plot_function(...):
    ...

matplotlib.pyplot.new_func = my_new_plot_function

并且您的新函数将可用于使用 pyplot 模块的其他模块。但是,正如评论中所述,没有必要这样做——从架构的角度来看,这绝对是不可取的。您甚至可以替换 pyplot 模块中的现有函数或 classes 来执行此操作 - 这称为猴子修补 - 除非您真的非常知道自己在做什么,否则您会发现它非常不可靠 - 并且即便如此,它的可维护性很差,并且在您的整个系统中都是一个晦涩的功能。

现在 - Pyplot 模块中有 classes - 你可以继承它们,并增强它们的行为 - 你可以在你的代码中导入你继承的 classes,从你自己的模块。也许继承不是在现代代码中添加它们的行为的最佳方法(首选所需方法的聚合和代理)——但这会起作用。

可以被子class的class是:

>>> [obj for obj in dir(pyplot) if isinstance(getattr(pyplot, obj), type)]
['Annotation', 'Arrow', 'Artist', 'AutoLocator', 'Axes', 'Button', 'Circle', 'Figure', 'FigureCanvasBase', 'FixedFormatter', 'FixedLocator', 'FormatStrFormatter', 'Formatter', 'FuncFormatter', 'GridSpec', 'IndexLocator', 'Line2D', 'LinearLocator', 'Locator', 'LogFormatter', 'LogFormatterExponent', 'LogFormatterMathtext', 'LogLocator', 'MaxNLocator', 'MultipleLocator', 'Normalize', 'NullFormatter', 'NullLocator', 'PolarAxes', 'Polygon', 'Rectangle', 'ScalarFormatter', 'Slider', 'Subplot', 'SubplotTool', 'Text', 'TickHelper', 'Widget', 'silent_list']