使用Python将类抽象化

时间:2019-04-28 17:58:58

标签: python abstract-class

我正在努力使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]
  • 我使用EFeatureObjectiveABC = 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)上运行,而SingletonObjectivesingle 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 :(得分:0)

如果您想要一个不能实例化但可以子类化的类,那么可以通过以下方法实现:

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`')