[英]Python Inherit from one class but override method calling another class?
[英]In Python, how can I inherit and override a method on a class instance, assigning this new version to the same name as the old one?
在Matplotlib,一个常见的问题是之间的不必要的白线Patch
对象与绘制pcolor
, pcolormesh
和contourf
(见这个问题,并为前两种这个问题,后者)。
我试图通过使用MethodType
向我的Axes
类/子类实例添加新方法来自动修复此MethodType
。 我这样做而不是子类化只是因为我想通过将GridSpec
对象的切片传递给Figure
实例上的add_subplot
方法来生成Axes
,而且我不知道如何使用某种子类化matplotlib.axes.Subplot
(但我欢迎建议)。 下面是一些示例代码:
from types import MethodType
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
f = plt.figure()
gs = GridSpec(2,1)
ax = f.add_subplot(gs[0,0])
def _pcolormesh(self, *args, **kwargs):
p = self.pcolormesh(*args, **kwargs)
p.set_edgecolor('face')
p.set_linewidth(0.2) # Will cover white lines, without making dot in corner of each square visible
return p
def _contourf(self, *args, **kwargs):
c = self.contourf(*args, **kwargs)
for _ in c.collections:
_.set_edgecolor('face')
return c
ax.mypcolormesh = MethodType(_pcolormesh, ax)
ax.mycontourf = MethodType(_contourf, ax)
在最后一行中,我希望能够编写ax.pcolormesh
而不是ax.mypcolormesh
,但这会引发RecursionError
,因为_pcolormesh
调用原始方法名称...现在别名为它自己。
那么,如何访问此Axes
实例上的方法、覆盖它并保留原始名称?
由于单独替换每个轴的方法比使用简单函数要多得多,因此最有效的方法是使用相应的函数创建 Python 文件myhacks.py
def pcolormesh(ax, *args, **kwargs):
p = ax.pcolormesh(*args, **kwargs)
p.set_edgecolor('face')
p.set_linewidth(0.2)
return p
并在需要 pcolormesh 的改进版本时使用它:
import matplotlib.pyplot as plt
import myhacks as m
# ...other imports
fig, ax = plt.subplots()
m.pcolormesh(ax, other_arguments)
这对于已经创建的文件也很有效,在其中可以简单地搜索替换"ax.pcolormesh("
与"m.pcolormesh(ax,"
(如有必要,使用正则表达式表示可能的其他轴名称)。
当然可以将matplotlib.axes.Axes
子类化以包含所需的函数。 由于这没有真正的好处,除了知道如何去做之外,我将其称为“学术解决方案”。
所以,我们可以再次为我们的自定义类创建一个文件myhacks.py
,将自定义类注册为 Matplotlib 的投影,
from matplotlib.axes import Axes
from matplotlib.projections import register_projection
class MyAxes(Axes):
name = 'mycoolnewaxes'
def pcolormesh(self,*args, **kwargs):
p = Axes.pcolormesh(self,*args, **kwargs)
p.set_edgecolor('face')
p.set_linewidth(0.2)
return p
register_projection(MyAxes)
并通过导入它并使用投影创建轴来使用它:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
import myhacks as m
fig = plt.figure()
gs = GridSpec(2,1)
ax = fig.add_subplot(gs[0,0], projection='mycoolnewaxes')
z = np.random.rand(10,13)
ax.pcolormesh(z)
plt.show()
嗯...我解决了,有点。 只需使用
ax._contourf = ax.contourf
它保存了旧方法的副本,然后,例如,
def _contourf(self, *args, **kwargs):
c = self._contourf(*args, **kwargs)
for _ in c.collections:
_.set_edgecolor('face')
return c
ax.contourf = MethodType(_contourf, ax)
它分配新方法来调用旧方法的副本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.