Используйте ту же функцию в множественном наследовании в Python - PullRequest
1 голос
/ 24 февраля 2020

Я хочу реализовать интерфейс с двумя классами с одинаковыми методами. После этого я создал 4-й класс, который наследует методы от двух классов.

Так что, если мне нужно использовать метод из класса hdfs_way, я передам параметр 1 в __init__ из use_FileSystem class, или 2, если я хочу использовать методы из класса hdfs_way.

Мой код работает нормально, но я не знаю, является ли это лучшим способом сделать что-то подобное.

from abc import ABCMeta, abstractmethod

class FileSystemInterface:
  __metaclass__ = ABCMeta
  @abstractmethod
  def list_dirs(self):
    pass

class hdfs_way(FileSystemInterface):
  def list_dirs(self):
    print("HDFS WAY")
    return None

class java_way(FileSystemInterface):
  def list_dirs(self):
    print("JAVA WAY")
    return None 

class use_FileSystem(hdfs_way,java_way):
  def __init__(self,type_api):
    self.type_api = type_api

  def list_dirs(self):
    if(self.type_api == '1'):
      java_way.list_dirs(self)
    else:
      hdfs_way.list_dirs(self)

a = use_FileSystem('2')
a.list_dirs()

Ответы [ 3 ]

1 голос
/ 24 февраля 2020

С концептуальной точки зрения то, что вы делаете, является приемлемым: если один и тот же атрибут метода существует в нескольких базовых классах, вы должны добавить явное переопределение в дочернем классе, возможно, используя реализацию базовых классов.

С точки зрения Pythoni c это также правильно: вы используете несвязанный метод из базовых классов и явно даете им объект. Pythoni c может быть больше, чем super, но это имеет смысл, только если ваша иерархия имеет промежуточный класс natural :

                                   Child

               BaseA                               BaseB

ImplementationA1 ImplementationA2   ImplementationB1 ImplementationB2
   methodX                                               methodX

Затем можно написать:

  def methodX(self):
    if(self.type_api == '1'):
      self.super(BaseA, self)()
    else:
      self.super(BaseB, self)()

(остерегайтесь супер ищет первый базовый класс BaseA или BaseB в приведенном выше коде, следовательно, промежуточный базовый класс ...)


В любом случае, в теоретической точке Представление: множественное наследование, если его часто рассматривают как сомнительный проект, и многие предпочитают шаблон содержания ( имеет вместо - ) в этом случае. Например, это запрещено на языке Java и, как известно, вызывает проблемы с обслуживанием (наследование алмазов) на языке C ++.

0 голосов
/ 25 февраля 2020

После некоторых исследований я вновь заявляю, что с помощью наследования это не лучшая идея для удовлетворения моих потребностей. Лучший способ - реализовать шаблон проектирования Abstract Factory,

Ниже приведен мой код после рефакторинга. :

from abc import ABCMeta, abstractmethod

class FileSystemInterface:
  __metaclass__ = ABCMeta

  @abstractmethod
  def list_dirs(self):
    pass

class HDFS_way(FileSystemInterface):
    def list_dirs(self):
      print("HDFS WAY")
      return None

class JAVA_way(FileSystemInterface):
  def list_dirs(self):
    print("JAVA WAY")
    return None 


class FileSystemFactory:
  HDFS_IMPL = 'HDFS'
  JAVA_IMPL = "JAVA"
  DEFAULT_IMPL= JAVA_IMPL

  @staticmethod
  def getFilesystem(implementation=None):
    if implementation is None:
      implementation = FileSystemFactory.DEFAULT_IMPL
    if(implementation == FileSystemFactory.JAVA_IMPL):
      return JAVA_way()
    else:
      return HDFS_way()

  @staticmethod
  def setDefault(implementation):
    FileSystemFactory.DEFAULT_IMPL = implementation



FileSystemFactory.setDefault(FileSystemFactory.HDFS_IMPL)
fs = FileSystemFactory.getFilesystem()
fs.list_dirs()
0 голосов
/ 24 февраля 2020

В вашей реализации list_dirs () в use_FileSystem вы вызываете родительский класс list_dirs с помощью java_way.list_dirs (self) или hdfs_way.list_dirs (self). То, как вы их вызывали, похоже на то, что вы создали функции как метод класса.

Для обозначения вызова является функцией родительского класса, я думаю, что лучше всего использовать слово super ()

class use_FileSystem(hdfs_way,java_way):
  def __init__(self,type_api):
    self.type_api = type_api

  def list_dirs(self):
    if(self.type_api == '1'):
      super(java_way, self).list_dirs()
    else:
      super(hdfs_way, self).list_dirs()
...