python最佳实践 - 类非常相似,但构造函数不同

时间:2017-06-02 15:41:10

标签: python class oop inheritance

我创建了四个类:experiment, experiment_type1, experiment_type2 and experiment_type3

experiment是一个抽象类,无法实例化。它有两种方法__init__(self)run(self),其中run(self)是抽象的。

experiment_type1experiment_type2来自实验。它们从__init__(self)继承experiment(因此它们共享相同的构造函数)但它们彼此不同地实现run(self)

我的问题在于experiment_type3课程。它也只有run(self)方法,与experiment_type1experiment_type2的实现方式不同,但它的构造函数需要另外一个参数。它的构造函数的格式为__init__(self, parameter)

理想情况下,我希望experiment_type3来自experiment。但是有一个构造函数不匹配。处理这个问题的最佳方法是什么?在这种情况下在python中编程。

修改 这是实验和experiment_type3的代码。正如你所看到的,它取决于不存在的self.epsilon。

将numpy导入为np 来自abc import ABC,abstractmethod 来自Bandit进口强盗

class experiment(ABC):
    def __init__(self, num_iter, bandit_list): #epsilon is the chance to explore, num_iter is num of iterations, bandit_list is the list of the bandits
        self.num_iter = num_iter
        self.bandit_list = bandit_list
        self.best_bandit = np.random.choice(len(bandit_list))

    @abstractmethod
    def run(self):
        raise NotImplementedError('derived class must implement run() method!')

class eg_experiment(experiment):
    def run(self):
        for iteration in range(self.num_iter):
            bandit = np.random.choice(len(self.bandit_list))
            if(np.random.random() > self.epsilon):
                bandit = self.best_bandit
            self.bandit_list[self.best_bandit].pull()
            self.best_bandit = np.argmax([bandit.current_mean for bandit in self.bandit_list])

2 个答案:

答案 0 :(得分:3)

正如评论所指出的那样,在父类super()上使用__init__可以为您提供所需内容。

class A:
    def __init__(self, parameter)
        self.parameter = parameter

class B(A):
    def __init__(self, parameter, new_parameter)
        super().__init__(parameter)
        self.new_parameter = parameter

或在你的情况下

class eg_experiment(experiment):
    def __init__(num_iter, bandit_list, epsilon):
        super().__init__(num_iter, bandit_list)  #Python3
        # super(experiment,self).__init__(num_iter, bandit_list) # Pythyon2.7
        self.epsilon = epsilon

答案 1 :(得分:0)

有一句谚语:"如果你的班级只有两种方法,一种是__init__,请改用函数。"特别是在这里,run方法没有共同的实现。你只有一堆具有类似签名的独立功能。

def run_experiment_one(num_iter, bandit_list):
    ...

def run_experiment_two(num_iter, bandit_list):
    ...

def run_experiment_three(num_iter, bandit_list, epislon):
    ...