Создание абстрактного класса в Python - PullRequest
1 голос
/ 28 апреля 2019

Я работал над тем, чтобы сделать EFeatureObjective абстрактным, я знал, что могу реализовать класс и просто сделать calculate_feature_scores абстрактным, но то, что я сделал -

class EFeatureObjective(bluepyopt.objectives.Objective):

    """EPhys feature objective"""

    def __init__(self, name, features=None):
        """Constructor
        Args:
            name (str): name of this object
            features (list of eFeatures): features used in the Objective
        """

        super(EFeatureObjective, self).__init__(name)
        self.name = name
        self.features = features

    def calculate_feature_scores(self, responses):
        """Calculate the scores for the individual features"""

        scores = []
        for feature in self.features:
            scores.append(feature.calculate_score(responses))

        return scores


class SingletonObjective(EFeatureObjective):

    """Single EPhys feature"""

    def __init__(self, name, feature):
        """Constructor
        Args:
            name (str): name of this object
            features (EFeature): single eFeature inside this objective
        """

        super(SingletonObjective, self).__init__(name, [feature])

    def calculate_score(self, responses):
        """Objective score"""

        return self.calculate_feature_scores(responses)[0]

    def __str__(self):
        """String representation"""

        return '( %s )' % self.features[0]
  • Я сделал EFeatureObjective как абстрактный, используя ABC = abc.ABCMeta('ABC', (object,), {'__slots__': ()}) и имел

        def calculate_feature_scores(self, responses):                                   
             pass
    

    как

     import abc                                                                           
    
     ABC = abc.ABCMeta('ABC', (object,), {'__slots__': ()})                               
    
    
     class EFeatureObjective(bluepyopt.objectives.Objective, ABC):                           
    
          """EPhys feature objective"""                                                       
          def __init__(self, name, features=None):                                            
                """Constructor                                                                  
    
                Args:                                                                           
                name (str): name of this object                                             
                features (list of eFeatures): features used in the Objective                
                """                                                                             
    
                super(EFeatureObjective, self).__init__(name)                                   
                self.name = name                                                                
                self.features = features                                                        
    
          @abc.abstractmethod                                                                 
          def calculate_feature_scores(self, responses):    
              pass
    
    
     class SingletonObjective(EFeatureObjective):
           .........
           def calculate_feature_scores(self, responses):                                   
               """Calculate the scores for the individual features"""                       
    
               scores = []                                                                  
               for feature in self.features:                                                
               scores.append(feature.calculate_score(responses))                        
    
               return scores     
    

    Затем я реализовал этот метод в SingletonObjective, проблема в синтаксисе, может ли это быть реализовано? features недоступны в SingletonObjective. В основном EFeatureObjective работает на (list of eFeatures), а SingletonObjective работает на single eFeature inside this objective.

  • Затем я назвал абстрактный класс EFeatureObjective абстрактный метод calculate_feature_scores внутри SingletonObjective как

     def calculate_feature_scores(self, responses):
         super(SingletonObjective, self).calculate_feature_scores(responses)
    

    но потом

     def calculate_score(self, responses):                                               
             """Objective score"""                                                           
    
             return self.calculate_feature_scores(responses)[0]  
    

    индекс будет ошибка.

Я потратил некоторое время на это, и теперь я хочу, чтобы EFeatureObjective был абстрактным, не создавая класс, работающий с различными версиями Python. Ценю любые ответы.

1 Ответ

0 голосов
/ 28 апреля 2019

Если вам нужен класс, который вы не можете создать, но можете создать подкласс, то вот способ сделать это:

class BaseClass(object):
  def __new__(cls):
    ''' If this is not a subclass being instanciated, then raise an error '''
    if cls is BaseClass:
      raise TypeError('Cannot instantiate this')
    return object.__new__(cls)

   AbstractMethod1 = None

   def __init_subclass__(cls):
     ''' Anytime subclasses are created, make sure they have the right methods '''
     if cls.AbstractMethod1 is None:
       raise TypeError('All subclasses of `base` must define `AbstractMethod1`')
...