gpt4 book ai didi

Python从任意类继承方法

转载 作者:行者123 更新时间:2023-12-01 00:48:40 24 4
gpt4 key购买 nike

我确信这将是一个重复的问题,但我似乎找不到单词来定位这个问题。

我有一组非常相似的模型,我想对其进行编码。除了单个函数/代码行之外,这些模型都是相同的。我想避免任何代码重复。让我们看看 MWE:

import numpy as np

class SinModel:
def __init__(self):
self.x = np.linspace(-np.pi, np.pi)
def run(self):
# Computations which are invariant of the function we use later
self.y = np.sin(self.x)
# More computations which are invariant of which funcion was used

我们的第二个模型将涉及相同的一系列计算,但中间会使用不同的函数(这里是余弦而不是正弦):

class CosModel:
def __init__(self):
self.x = np.linspace(-np.pi, np.pi)
def run(self):
# Computations which are the same as in SinModel
self.y = np.cos(self.x)
# More computations which are the same as in SinModel

这里有很多代码重复。有没有更好的方法来实现这些模型?我希望能够创建一个类 Model ,它可以从任意类继承不同的函数。

需要注意的是,根据模型的不同,在模型之间更改的函数可能会从 self 获取不同的参数。

最佳答案

您要查找的词是继承(允许类继承并扩展/专门化父类)和“模板方法”设计模式(这可能是最常见的设计模式 - 每个人都会自己发现的模式)早在阅读设计模式之前)。

扩展您的 MWE:

import numpy as np

class ModelBase(object):
def __init__(self):
self.x = np.linspace(-np.pi, np.pi)

def run(self):
# Computations which are invariant of the function we use later

self.y = self.compute_y()

# More computations which are invariant of which funcion was used


def compute_y(self):
raise NotImplementedError("class {} must implement compute_y()".format(type(self).__name__))



class SinModel(ModelBase):
def compute_y(self):
return np.sin(self.x)

class CosModel(ModelBase):
def compute_y(self):
return np.cos(self.x)

话虽这么说,在初始化程序之外创建实例属性(__init__ 方法)被认为是不好的做法 - 当初始化程序返回时,对象应该完全初始化(定义了它的所有属性),因此它如果可能的话,最好将 self.y = self.compute_y() 行移至初始值设定项,或者,如果 self.y 始终仅依赖于 self .x,使其成为计算属性:

class ModelBase(object):
def __init__(self):
self.x = np.linspace(-np.pi, np.pi)

@property
def y(self):
return self._compute_y()

def _compute_y(self):
raise NotImplementedError("class {} must implement _compute_y()".format(type(self).__name__))


def run(self):
# Computations which are invariant of the function we use later

# no need to explicitely set self.y here, just use `self.y`
# and it will delegate to self._compute_y()
#(you can't set it anymore anyway since we made it a readonly propery)

# More computations which are invariant of which funcion was used



class SinModel(ModelBase):
def _compute_y(self):
return np.sin(self.x)

class CosModel(ModelBase):
def _compute_y(self):
return np.cos(self.x)

此时,您不一定再需要子类,至少如果这是唯一发生变化的事情 - 您只需将适当的函数作为回调传递给您的模型类即可,即:

class Model(object):
def __init__(self, compute_y):
self.x = np.linspace(-np.pi, np.pi)
self._compute_y = compute_y

@property
def y(self):
return self._compute_y(self)

def run(self):
# code here


cos_model = Model(lambda obj: np.cos(obj.x))
cos_model.run()

sin_model = Model(lambda obj: np.sin(obj.x))
sin_model.run()

关于Python从任意类继承方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56738922/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com