2010-02-09 2 views
37

J'ai essayé de sous-classer le threading.Condition plus tôt aujourd'hui mais cela n'a pas fonctionné. Voici la sortie de l'interpréteur Python lorsque je tente de sous-classe la classe threading.Condition:Erreur lors de l'appel des bases de la métaclasse: L'argument function() 1 doit être le code, et non le

>>> import threading 
>>> class ThisWontWork(threading.Condition): 
...  pass 
... 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: Error when calling the metaclass bases 
    function() argument 1 must be code, not str 

Quelqu'un peut-il expliquer cette erreur? Merci!

Répondre

61

Vous obtenez cette exception car, en dépit de son nom de classe, threading.Condition est une fonction et vous ne pouvez pas sous-classer des fonctions.

>>> type(threading.Condition) 
<type 'function'> 

Cette non très utile message d'erreur a été raised on the Python bugtracker, mais il a été marqué « ne réglera pas. »

+0

Étrange, je ne pensais pas à vérifier son type. Les docs semblent être un peu trompeurs parce qu'ils disent (http://docs.python.org/library/threading.html) "class threading.Condition ([lock])" qui semble un peu trompeur. Quoi qu'il en soit, merci d'avoir clarifié ça :). –

+1

Je le vois aussi bien en utilisant par erreur un module comme un baseclass: class Command (main.cmdroot.list.hosts) plutôt que la commande correcte (main.cmdroot.list.hosts.Command) – FDS

+1

Une autre cause commune est de dériver de une classe de base qui a un décorateur. Le décorateur peut également changer le type de la classe de base en "type <'function'>". –

25

Problème différent de OP, mais vous pouvez également obtenir cette erreur si vous essayez de sous-classer un module au lieu d'une classe (par exemple, vous essayez d'hériter My.Module au lieu de My.Module.Class). Bravo à this post pour m'aider à comprendre cela.

TypeError: Error when calling the metaclass bases

For this one, the answer is that you probably named a python class the same thing as the module (i.e., the file) that it's in. You then imported the module and attempted to use it like a class. You did this because you, like me, were probably a Java programmer not that long ago :-). The way to fix it is to import the module.class instead of just the module. Or, for sanity's sake, change the name of the class or the module so that it's more obvious what's being imported.

16

En ce qui concerne le sous-classement d'un module, c'est une erreur vraiment facile à faire si vous avez, par exemple, la classe Foo définie dans un fichier Foo.py. Lorsque vous créez une sous-classe de Foo dans un fichier différent, vous pourriez accidentellement faire ce qui suit (ce qui est une tentative de sous-classe un module et se traduira par une erreur):

import Foo 
class SubclassOfFoo(Foo): 

quand vous avez vraiment besoin de faire soit :

from Foo import Foo 
class SubclassOfFoo(Foo): 

ou:

import Foo 
class SubclassofFoo(Foo.Foo): 

S'il vous plaît noter: Cette réponse devrait vraiment être un commentaire sur la réponse qui mentionne un module sous-classement, mais je c N'en faites pas un commentaire à cause du comportement de StackOverflow décrit dans cet article: https://meta.stackexchange.com/questions/23211/how-do-i-add-a-comment-to-an-answer Ne le votez pas simplement à cause de ça.

+0

c'est une bonne raison de ne pas nommer vos modules comme des classes :) – Anentropic

2

J'ai rencontré le même problème. Enfin résolu en prenant un regard vif sur le code et c'est là les TypeError que les alarmes sur une chaîne au lieu du code se réalise ..

Class Class_name(models.model): //(gives a TypeError of 'str' type) 

« Et »

Class Class_name(models.Model): // is the correct one. 

Notez que l'erreur spécifique est à propos en raison d'une seule lettre minuscule au code "Modèle" qui à son tour en fait une chaîne

Questions connexes