Python 类是否可以从不同的文件继承方法(或子类)?这是不是;蟒蛇的;?
在尝试构建一个科学的Python包时,为了清晰起见,我的目标是将关键功能分离到不同的.py文件中。具体来说,在我看来,将一个模型的复杂数值计算拆分为一个python文件(比如“processing.py”),并将用于可视化的绘图例程拆分为另一个python文件(“plotting.py”)似乎是合乎逻辑的 为了方便和内存高效的使用,模型类应该能够继承所有绘图方法,使用户可以轻松访问这些方法,同时通过将科学数字代码与可视化代码分离,使代码易于维护和读取 我在下面概述了实现这一目标的愿景,但我正在努力解决如何在Python/如果有更好的OOP风格可用的话实现这一点 例如,在plotting.py中:Python 类是否可以从不同的文件继承方法(或子类)?这是不是;蟒蛇的;?,python,class,oop,inheritance,Python,Class,Oop,Inheritance,在尝试构建一个科学的Python包时,为了清晰起见,我的目标是将关键功能分离到不同的.py文件中。具体来说,在我看来,将一个模型的复杂数值计算拆分为一个python文件(比如“processing.py”),并将用于可视化的绘图例程拆分为另一个python文件(“plotting.py”)似乎是合乎逻辑的 为了方便和内存高效的使用,模型类应该能够继承所有绘图方法,使用户可以轻松访问这些方法,同时通过将科学数字代码与可视化代码分离,使代码易于维护和读取 我在下面概述了实现这一目标的愿景,但我正在努
class ItemPlotter(object):
def visualisation_routine1(self):
plt.plot(self.values) # where values are to be acquired from the class in processing.py somehow
在processing.py中:
class Item(object):
def __init__(self, flag):
if flag is True:
self.values = (1, 2, 3)
else:
self.values = (10, 5, 0)
from plotting.py import ItemPlotter
self.plots = ItemPlotter()
这将导致使用以下命令行:
from processing.py import Item
my_item = Item(flag=True)
# Plot results
my_item.plots.visualisation_routine1()
我的实际代码将比这更复杂,并且可能项将具有大型数据集的属性,因此我希望我需要避免复制这些属性以提高内存效率
请问,我的视力可能吗,或者甚至是一种蟒蛇式的方法?
有什么意见吗。欢迎使用面向对象或有效的方法来实现这一点
另外,我的目标是Py2.7和Py3的兼容性
为了方便和内存高效的使用,模型类应该能够继承所有绘图方法,使用户可以轻松访问这些方法,同时通过将科学数字代码与可视化代码分离,使代码易于维护和读取
正如Jon所指出的,您实际上是在描述组合,而不是继承(无论如何,这是一种方式)
实现所需功能的一种方法是创建一个抽象类,用于定义“项目绘图仪”的接口和item
的实例。您可以允许Item
的客户端轻松打印Item
实例封装的数据,方法是将打印委托给注入的ItemPlotter
这种方法允许每个类都尊重代码,并使代码更易于理解、维护和测试。如果愿意,可以在单独的Python模块中定义Item
和ItemPlotter
from abc import abstractmethod, ABC
class AbstractItemPlotter(ABC):
@abstractmethod
def plot(self, values):
return
class ItemPlotter(AbstractItemPlotter):
def plot(self, values):
# plt.plot(values)
print('Plotting {}'.format(values))
pass
class Item(object):
def __init__(self, flag: bool, plotter: AbstractItemPlotter):
self._plotter = plotter
if flag:
self.values = (1, 2, 3)
else:
self.values = (10, 5, 0)
def visualisation_routine1(self):
self._plotter.plot(self.values)
if __name__ == '__main__':
item = Item(flag=True, plotter=ItemPlotter())
item.visualisation_routine1()
输出
绘图(1,2,3)
编辑
该代码使用Python 3.5.2进行了测试。我不能确定它是否能在Python 2.7中正常工作。这既不是继承也不是子类化,而是组合。是的,可以使用其他地方类的实例作为属性,但是您仍然应该将导入放在文件的顶部。您能提供一个工作示例吗?当我尝试此操作时,我得到AttributeError:“ItemPlotter”对象没有属性“vales”。谢谢你的帮助。。。是的,没错,没有。因为,再一次,您不是子类化。在
项的实例中有一个项绘图仪的实例
,但它们不是同一个对象(它们不共享自身
)。也许Item
应该继承自ItemPlotter
,反之亦然。或者,您可以在实例化ItemPlotter时传递Item的实例(即self
),或者在调用visualization\u routine1
时传递该实例。另外请注意,创建例如self.plotter=ItemPlotter(self.values)
实际上并不复制值,它只是意味着两个实例共享对同一对象的引用。但是,如果您希望ItemPlotter
成为“类中的混合”,则需要Item
来继承它。感谢您的帮助以及指向良好OOP样式的链接。这看起来很棒。我想知道为什么我们需要创建AbstractItemPlotter类——我是否需要将AbstractItemPlotter中ItemPlotter的每个方法都复制为“abstractmethod”才能工作?此外,我想知道你认为这与@Daniel Roseman在之前的帖子评论中的想法相比如何。是否使用self.plotter=ItemPlotter(self)简化plotter类的初始化,并在ItemPlotter init中保存对self的引用?Thanks@IanRoberts“我是否需要将AbstractItemPlotter中ItemPlotter的每个方法复制为一个“abstractmethod”以使其正常工作?”只有在实现之间可能有所不同的方法。通用方法可以在基类中实现。另见。至于第二个问题,Daniel的方法似乎是另一种体面的方法,尽管我不知道他是否真的打算将ItemPlotter
存储在Item
中。这会使课程更加紧密,这通常是不好的。