【问题标题】:How do I add a method to a class from a third-party Python module without editing the original module如何在不编辑原始模块的情况下从第三方 Python 模块向类添加方法
【发布时间】:2014-02-26 13:12:14
【问题描述】:

我正在使用 matplotlib 工具包 (mpl_toolkits.basemap.Basemap) 中 basemap 模块中的 Basemap 对象。在basemap__init__.py 文件(即mpl_toolkits.basemap.__init__ 模块)中,定义了一个在地图上绘制纬度的方法drawparallels。我的目标是复制该方法以创建一个名为drawmlat 的新方法,进行一些调整以绘制磁纬度而不是地理纬度。

理想情况下,我希望新的 drawmlat 等同于原始的 drawparallel(我可以使用 BasemapInstance.drawmlats() 调用的 Basemap 实例的绑定方法),并且我不想修改原始的文件。我将如何做到这一点?

我已经尝试过“配方”MyObj.method = MethodType(new_method, None, MyObj) 的变体,但没有在原始源文件中放置任何内容,新方法无法从 Basemap 模块访问全局变量等(例如在其 __init__.py 中定义) .

如果我似乎误解了什么,我可能有 - 我或多或少是面向对象编程的新手。

【问题讨论】:

标签: python class methods


【解决方案1】:

Python 是高度可修改的。只需将您的函数添加到

from mpl_toolkits.basemap import Basemap


def drawmlat(self, arg1, arg2, kw=something):
    pass

Basemap.drawmlat = drawmlat

现在Basemap 类有一个drawmlat 方法;在实例上调用它,self 将绑定到实例对象。在实例上查找方法时,该函数将自动绑定为您的方法。

Basemap.__init__ 方法中定义的任何您需要关心的都是self 上的属性。

查看mpl_toolkits.basemap.__init__ 模块后,我确实看到drawparallel 方法依赖于几个 全局变量;您可以将模块中的那些导入到您自己的命名空间中:

from mpl_toolkits.basemap import Basemap, _cylproj, _pseudocyl

这与您进行的其他导入没有什么不同;原始的drawparallel 方法还依赖于import numpy as npfrom matplotlib.lines import Line2D,它们使npLine2D 在原始模块中成为全局变量。

【讨论】:

  • 不起作用。 mpl_toolkits.basemap 模块(文件夹)(注意小写 b)包含文件 __init__.py,其中定义了 Basemap 类(大写 B)。 Basemap 类的方法使用在此 __init__.py 文件中定义的全局变量,但在 Basemap 类之外定义。当我听从你的建议,而是用已经存在的drawparallels 方法的相同副本替换你的虚拟drawmlat 函数时,我得到NameError: global name '_cylproj' is not defined 其中_cylproj 是我提到的全局变量之一,它在drawparallels 方法。
  • @cmeeren:您可以将该模块中的其他全局变量导入您自己的模块中。我来看看确切的源代码。
  • @cmeeren:我很抱歉,我以为你在谈论 Basemap.__init__ 方法,而不是 mpl_toolkits.basemap.__init__ 模块。
  • @martijn-pieters,我可以看到我应该对此更清楚(更新)。谢谢你的回答。我的评论空间不足。 :p
  • @martijn-pieters,您可以在此处查看有问题的__init__.py 文件:dropbox.com/s/tvfht9jcyw03a61/__init__.py
猜你喜欢
  • 2019-01-09
  • 1970-01-01
  • 2014-05-31
  • 1970-01-01
  • 2014-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多