2017-09-08 2 views
1
from abc import ABCMeta, abstractmethod 

class Shape(object): 

    _metaclass_ = ABCMeta 

    @abstractmethod 
    def calculate_area(self): 
     """ Returns the area of the shape 
     :return str: A string of the area. """ 
     pass 

    def print_area(self): 
     area = self.calculate_area() 
     print("Area is " + area) 

Dans cet exemple, toutes les formes calculent leur zone différemment, mais toutes les classes enfants ont une méthode commune qui imprime la zone actuelle. Pycharm se plaint de area dans la dernière ligne, disant qu'il a le type None au lieu de TypeVar('AnyStr', str, unicode). Cela a du sens, car calculate_area ne renvoie rien. D'autre part, calculate_area est une méthode abstraite et donc il ne sera pas appelé directement sous Shape, il sera implémenté différemment par les classes enfants. Évidemment, le type de retour de calculate_area ne peut pas être appliqué sur les classes enfant, mais PyCharm ne devrait pas attendre pour me dire que le type est erroné puisque calculate_area est abstrait? Je me demande si Pycharm est en faute, ou je suis et ce n'est pas la façon de mettre en œuvre cette classe abstraite et je devrais essayer une approche différente?Indication de type Pycharm avec méthodes abstraites

Ceci est un exemple minimal. Le code sur lequel je travaille a une méthode principale (non-abstraite) dans la classe abstraite qui appelle beaucoup de méthodes abstraites. La fonction principale fonctionne généralement dans toutes les classes enfant, mais les méthodes abstraites doivent être remplacées pour l'objectif spécifique des classes enfants. Par conséquent, j'ai des erreurs d'indication de type partout.

Répondre

0

Le problème est que calculate_area dans votre exemple renvoie implicitement None. Vous pouvez juste "réparer" en retournant une chaîne vide. Ce serait attraper les cas où une sous-classe retourne juste super(Subclass, self).calculate_area() dans son calculate_area:

class Shape(object): 

    _metaclass_ = ABCMeta 

    @abstractmethod 
    def calculate_area(self): 
     """ Returns the area of the shape 
     :return str: A string of the area. """ 
     return "" 

    def print_area(self): 
     area = self.calculate_area() 
     print("Area is " + area) 

Cependant, il est pas considéré comme un bon style pour ajouter des chaînes. Donc si vous utilisez format le problème n'existera pas en premier lieu car format peut traiter n'importe quel objet qui a une méthode __repr__ ou __str__ (pratiquement n'importe quel objet). Donc, cela fonctionnerait même si calculate_area renvoie None ou au lieu d'une chaîne, il renvoie un nombre:

class Shape(object): 

    _metaclass_ = ABCMeta 

    @abstractmethod 
    def calculate_area(self): 
     """ Returns the area of the shape 
     :return str: A string of the area. """ 
     pass 

    def print_area(self): 
     area = self.calculate_area() 
     print("Area is {}".format(area))