“Ne peut pas instancier une classe abstraite ... avec des méthodes abstraites” de la classe qui ne doit avoir aucune méthode abstraite

Prendre exemple minimal:

import abc

class FooClass(object):
  __metaclass__ = abc.ABCMeta

  @abc.abstractmethod
  def FooMethod(self):
    raise NotImplementedError()


def main():
  derived_type = type('Derived', (FooClass,), {})

  def BarOverride(self):
    print 'Hello, world!'
  derived_type.FooMethod = BarOverride

  instance = derived_type()

De course main() vous obtient:

TypeError: Can't instantiate abstract class Derived with abstract methods FooMethod

(À l'exception se produit sur la instance = derived_type() ligne.)

Mais FooMethod ne devrait pas être abstrait: j'ai remplacé avec BarOverride. Alors, pourquoi est-ce que cela soulève des exceptions?

Avertissement: Oui, je pourrais utiliser explicitement class de la syntaxe, et de faire exactement la même chose. (Et même mieux, je peux le faire fonctionner!) Mais c'est un minimum de cas de test, et le plus grand exemple est de créer dynamiquement des classes. 🙂 Et je suis curieux de savoir pourquoi cela ne fonctionne pas.

Edit: Et pour empêcher les autres évident de non-réponse: je ne veux pas passer BarOverride dans le troisième argument de type: Dans l'exemple réel, BarOverride doit avoir derived_type lié à elle. Il est plus facile de le faire si je peux définir BarOverride après la création de derived_type. (Si je ne peux pas faire cela, alors pourquoi?)

L'abstraction d'une classe est déterminé lors de construction de classe. Pourquoi ne pas simplement inclure FooMethod dans le dictionnaire, alors que la création de la classe?
BarOverride, dans l'exemple réel, doit avoir de la classe dérivée lié à elle. Création de la fonction par la suite est la meilleure façon d'atteindre cet.
Je n'ai pas ce point. Qu'entendez-vous par "doit avoir la classe dérivée lié à elle"?

OriginalL'auteur Thanatos | 2011-11-10