【问题标题】:python method override with multiple inheritance and instancingpython方法覆盖多重继承和实例化
【发布时间】:2017-09-13 12:26:28
【问题描述】:

这是我的代码 - 我的 base_file.py

class modify_file(object):
    def modify_file_delete_obj():
        print "modify file here"

    def modify_file_add_attributes():
        print "modify file here"
        return ["data"]

class task_list(object):
    modify_file_instance = modify_file() #problem part when accessing from project1.py
    def check_topology():
        data = modify_file_instance.modify_file_add_attributes()
        #use this data further in this method


    def check_particles():
        print "check for particles"

project1.py 文件

import base_file as base_file
class project1(base_file.modify_file,base_file.task_list):
    #overriding method of modify_file class
    def modify_file_add_attributes(self):
        print "different attributes to modify"
        return ["different data"]

这个想法是为大多数项目运行 base_file.py,并在需要时为项目特定的项目运行。 但是当我运行该方法时

"check_topology" from project1.py 

modify_file 类是从 base_file.py 而不是 project1.py 派生的

So the output is still ["data"] not ["different data"]

【问题讨论】:

  • 在语义上,猫是宠物,但宠物并不总是猫。所以继承有点颠倒。意思是cat 应该是pet 的子类(它可以是animal 的子类)。
  • 同意.. 我的实际代码在不同的上下文中...
  • 我猜你应该从pet类继承dogcat类。
  • @user2015144 没问题,但是一个误导性的例子很难推理 - 这使得提出适当的解决方案变得困难/不可能。
  • 在我的实际代码中,cat 类实际上有一些 ui 代码多线程,而 dog 类有一个套接字监听,但有一些更简单的方法,我想从单独的文件中重写(对于 pet 类那就是继承狗和猫)

标签: python inheritance multiple-inheritance


【解决方案1】:

如果您想正确使用继承,请定义一个基类Pet,它提供了一种被特定宠物覆盖的方法。

class Pet(object):
    def talk(self):
        pass

class Cat(Pet):
    def talk(self):
        return "meow"

class Dog(Pet):
    def talk(self):
        return "woof"

pets = [Cat(), Dog(), Cat()]
for p in pets:
    print(p.talk())

# Outputs
#   meow
#   woof
#   meow

(我将Pet.talk 应该做什么的问题留给另一个问题。)

【讨论】:

    【解决方案2】:

    您将object compositionmultiple inheritance 混淆了。

    task_list 类在创建modify_file 类的内部实例时使用对象组合。但是这里有一个问题,您将它创建为一个类属性,这意味着它将被task_list 的所有实例共享。它应该是在 __init__ 方法中创建的 instance 属性

    class task_list(object):
        def __init__(self):
            super(task_list, self).__init__()
            self.modify_file_instance = modify_file()
    
        def check_topology(self):
            data = self.modify_file_instance.modify_file_add_attributes()
    

    project1 类使用多重继承,而实际上它应该使用单继承。它是task_list 的一种,所以继承modify_file 也没有任何意义。相反,它应该创建自己的 modify_file 内部子类 - 即使用对象组合,就像 task_list 类所做的那样:

    # custom modify_file sub-class to override methods
    class project1_modify_file(base_file.modify_file):
        def modify_file_add_attributes(self):
            print "different attributes to modify"
            return ["different data"]
    
    class project1(base_file.task_list):
        def __init__(self):
            super(project1, self).__init__()
            self.modify_file_instance = project1_modify_file()
    

    现在您有了一个一致的界面。所以当project1.check_topology()被调用时,它会依次调用task_list.check_topology()(通过继承),然后访问self.modify_file_instance(通过组合):

    >>> p = project1()
    >>> p.check_topology()
    different attributes to modify
    

    【讨论】:

      【解决方案3】:

      在您的dog 类中,您正在重新构造cat 的一个实例,这个实例(和cat 类型)不知道它们是由pets 在其他地方继承的。

      所以你自然可以试试:

      class cat(object):
          def meow(self):
              self.sound = "meow"
              return self.sound
      
      class dog(object):
          def woof(self):
              return self.meow()
      
      
      class pets(cat,dog):
          def meow(self):
              self.sound = "meow meow"
              return self.sound
      
      print(pets().woof())
      

      这些实际名称仍然没有意义,但您告诉它们是假名称,所以没关系。

      【讨论】:

      • 这个想法是在一个实例中调用 dog,在另一个实例中调用 pets
      猜你喜欢
      • 1970-01-01
      • 2015-09-19
      • 2011-06-14
      • 1970-01-01
      • 2012-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多