Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从另一个子类继承的“无法创建一致的方法解析顺序”_Python_Python 3.x_Oop_Inheritance - Fatal编程技术网

Python 从另一个子类继承的“无法创建一致的方法解析顺序”

Python 从另一个子类继承的“无法创建一致的方法解析顺序”,python,python-3.x,oop,inheritance,Python,Python 3.x,Oop,Inheritance,我正在修改Python中的OOP,并尝试从另一个子类继承属性,但我不知道如何或是否可能。以下是我到目前为止的情况: class Employee: def __init__(self, first, last, pay): self.first = first self.last = last self.pay = pay def increase_pay(self, multiplier): self.pay = int(self.pay * multip

我正在修改Python中的OOP,并尝试从另一个子类继承属性,但我不知道如何或是否可能。以下是我到目前为止的情况:

class Employee:
  def __init__(self, first, last, pay):
    self.first = first
    self.last = last
    self.pay = pay
  def increase_pay(self, multiplier):
   self.pay = int(self.pay * multiplier)

class Developer(Employee):
  def __init__(self, first, last, pay, prog_lang):
    Employee.__init__(self, first, last, pay)
    self.prog_lang = prog_lang
    self.email = first.lower() + '.' + last.lower() + '@outlook.com'

class beta_Tester(Employee, Developer):
  def __init__(self, first, last, pay, prog_lang, platform):
    self.platform = platform    
我收到的错误是:

Traceback (most recent call last):
  File "main.py", line 33, in <module>
    class beta_Tester(Employee, Developer):
TypeError: Cannot create a consistent method resolution
order (MRO) for bases Employee, Developer
在子类的init方法中使用super 您的beta_测试人员继承自员工和开发人员。因为开发人员已经从Employee继承了Python,所以现在无法确定首先查找方法的类。您不需要在这里命名开发人员的所有基类;只是从那个类继承。 这是您的固定代码:

class Employee:
  def __init__(self, first, last, pay):
    self.first = first
    self.last = last
    self.pay = pay


  def increase_pay(self, multiplier):
   self.pay = int(self.pay * multiplier)

emp_1 = Employee('David', 'Jackson', 35000)

print (emp_1.pay)

emp_1.increase_pay(1.2)

print (emp_1.pay)

class Developer(Employee):
  def __init__(self, first, last, pay, prog_lang):
    super().__init__(first, last, pay)
    self.prog_lang = prog_lang
    self.email = first.lower() + '.' + last.lower() + '@outlook.com'



dev_1 = Developer('James', 'McCarthy', 70000, 'C++',)

print(dev_1.first)
print(dev_1.email)


class beta_Tester(Developer):
  def __init__(self,first, last, pay, prog_lang, platform):
    self.platform = platform

bt_1 = beta_Tester('Jonas', 'Andersen', 45000, 'C#', 'Mobile')

print(bt_1.platform)

@梅尔达德普回答得很好

我想我应该让它容易些

假设有两个类A和B

B继承自A

现在您正在创建一个新的C类

如果您从B继承,那么您已经从A继承了。无需在类CA,B中编写

注意CB,A不会给你错误 但是CA,B会的

另一件事是你应该使用Super.\uuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu__ 在进行混合继承时,这可能并不方便,因为有超过1个不同的超类需要调用classname1.\uuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,classname2.\uuuuuuuuuuuuuuuuuu init

另外,如果希望在超类中定义属性,请调用类名。\uuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu 你会得到一个错误

比如说

printb1_1.first将给出一个错误 要解决这个问题,请使用开发人员


不要忘记这个开发人员的自我。uuu init_uuu从子类调用uuu init_uu

方法解析顺序MRO由C3线性化算法定义,这听起来很复杂,但实际上可以归结为:类、它的父类、它们的父类等需要根据两个条件放在一个列表中:

每个班级都出现在其家长面前 如果一个类从多个类继承,则其父类将显示在同一个类中 按类语句中的顺序排列。也就是说,给定AB,C,D类,A的MRO将在C之前有B,这将在D之前。当然,A出现在所有3之前 您应该能够看到问题:根据此算法,beta_Tester的MRO必须根据第一条规则在雇主之前包含开发者,但根据第二条规则,雇主必须在开发者之前。在这种情况下,您可以简单地交换这两个类来解决问题,但是从来没有任何理由继承一个类a和从a继承的另一个类。只需将a一起删除即可

# Developer is already a descendent of Employee, so BetaTester will be, too
class BetaTester(Developer):
   ...
要确保调用了每个类的uuu init_uuu方法,请使用super确保每个uuu init_uuu调用链中的下一个方法。这里最重要的规则是确保如果一个类将参数添加到uuu init uuuuuu,它必须确保不会将它们传递到下一个uuuu init uuuuuu。同时,它必须接受任意关键字参数,并确保传递它们。关键字参数使您更容易集中精力处理需要处理的参数,而只传递不需要处理的参数

class Employee:
    def __init__(self, first, last, pay, **kwargs):
        super().__init__(**kwargs)
        self.first = first
        self.last = last
        self.pay = pay
    def increase_pay(self, multiplier):
        self.pay = int(self.pay * multiplier)


class Developer(Employee):
    def __init__(self, prog_lang, **kwargs):
        super().__init__(**kwargs)
        self.prog_lang = prog_lang
        self.email = "{}.{}@outlook.com".format(self.first.lower(), self.last.lower())


class BetaTester(Developer):
    def __init__(self, platform, **kwargs):
        super().__init__(**kwargs)
        self.platform = platform    


b = BetaTester(first="Bob", last="Jones", pay=90000, prog_lang="Python", platform="Unix")

您遇到了什么具体错误?理想情况下,一个好的软件应该只有最短的代码来演示一个特定的问题——如果任何一行代码对你的观点都不是必需的,那么这行代码和任何依赖它的东西都不应该出现在这里。@charlesduff抱歉,我是第一篇文章的新手。让我将错误添加到帖子中!谢谢你,这很有帮助!现有的答案对于问题是什么猜测正确,但在问题中显示它有助于其他人跟进,并使其他有相同问题的人更容易搜索您的问题及其答案。顺便说一句,由于这只发生在Python 3中,我为该语言版本添加了一个标记;由于重现问题只需要类定义,所以我放弃了所有其他内容。如果您打算在Developer中使用super,那么您也应该在Employee中使用它,即使Employee只从object继承。您不知道从Employee或Developer继承的其他类也可能从其他类继承,Employee不一定是MRO对象中的最后一个类。