Seite 1 von 1

Selbsterstellte Listklasse wirft TypeError

Verfasst: Donnerstag 4. Dezember 2008, 19:35
von Thuught
Hallo,
Ich möchte mir meinen eigenen Listentyp erstellen.
Leider klappt das nichtganz so , wie ich mir das vorstelle:

Code: Alles auswählen

>>> class Vektoren(list):
... 	pass
... 
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
TypeError: Error when calling the metaclass bases
    list() takes at most 1 argument (3 given)

>>> class DefaultDict(dict):
... 	pass
... 
>>> 
Wäre echt nett, wenn mir einer sagen könnte, was hier falsch ist?

Verfasst: Donnerstag 4. Dezember 2008, 21:25
von BlackJack
Hm, kann ich nicht nachvollziehen:

Code: Alles auswählen

In [204]: class Vektoren(list):
   .....:     pass
   .....:

Verfasst: Donnerstag 4. Dezember 2008, 21:25
von Zap
Ich hab noch nie von list erben müssen, aber ich kann deinen Fehler nicht nachvollziehen

Code: Alles auswählen

In [10]: class T(list):
   ....:     def __repr__(self):
   ....:         return "MyList%s" % list.__repr__(self)
   ....:
   ....:

In [11]: T()
Out[11]: MyList[]

Verfasst: Freitag 5. Dezember 2008, 10:49
von helduel
Moin,

was für eine Python-Version benutzt du?

Das Problem kann ich so reproduzieren:

Code: Alles auswählen

>>> __metaclass__ = list
>>> class V: pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Error when calling the metaclass bases
    list() takes at most 1 argument (3 given)
New-Style-Classes ignorieren das globale __metaclass__, die klassischen Klassen nicht. Du hast wahrscheinlich, wie oben, list als globale Metaklasse definiert. Beim Instanzieren der Metaklasse werden drei Argumente übergeben, aber list erwartet nur eine.

Mit New-Style-Klassen funktioniert es aber:

Code: Alles auswählen

>>> __metaclass__ = list
>>> class V(list): pass
... 
Du benutzt wahrscheinlich eine Python-Version, die noch keine New-Style-Klassen kennt - oder zumundest list noch keine solche ist.

Gruß,
Manuel

Verfasst: Freitag 5. Dezember 2008, 10:56
von Thuught
Mein Programm heißt Active(state)python 2.6 und ich benutze die pywin32extension built 2.11.
Ist das zu empfehlen?

Verfasst: Freitag 5. Dezember 2008, 11:31
von helduel
Thuught hat geschrieben:Mein Programm heißt Active(state)python 2.6 und ich benutze die pywin32extension built 2.11.
Ist das zu empfehlen?
Ich kenne ActivePython nicht, aber die Python Version 2.6 sollte diese Probleme nicht haben (habe es mit 2.6 getestet).

Verfasst: Freitag 5. Dezember 2008, 13:11
von Rebecca
Thuught, du hast nicht zufaellig den Namen list ueberschrienen?

Code: Alles auswählen

>>> list = [1, 2, 3]
>>> class A(list): pass
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Error when calling the metaclass bases
    list() takes at most 1 argument (3 given)

Verfasst: Freitag 5. Dezember 2008, 14:54
von Thuught
Rebecca hat geschrieben:Thuught, du hast nicht zufaellig den Namen list ueberschrienen?

Code: Alles auswählen

>>> list = [1, 2, 3]
>>> class A(list): pass
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Error when calling the metaclass bases
    list() takes at most 1 argument (3 given)
Doch! Jedesmal.
Danke dir. jetzt klappts wie von Zauberhand
Mir war nicht bewusst, dass man die Variabel "list" für ne Liste besser nicht vergeben sollte. :(
Wobei gestern

Code: Alles auswählen

class test(type([])):
      pass
auch nicht geklappt hatte, obwohl es heute trotz dem Code von dir hinhaut.

Verfasst: Freitag 5. Dezember 2008, 15:04
von derdon

Code: Alles auswählen

In [1]: type([])
Out[1]: <type 'list'>

In [2]: <type 'list'>
------------------------------------------------------------
   File "<ipython console>", line 1
     <type 'list'>
     ^
SyntaxError: invalid syntax
Reicht das als Erklärung?

Verfasst: Freitag 5. Dezember 2008, 16:09
von str1442
@derdon

Das ist doch bloß eine Stringrepräsentation. "type([])" klappt auch, wobei man solche Konstrukte natürlich nicht verwenden sollte.

python -c "print list"
<type 'list'>

Verfasst: Freitag 5. Dezember 2008, 16:11
von derdon

Code: Alles auswählen

In [7]: list == type(list()) == type([])
Out[7]: True
Hast Recht. Sollte man aber nicht machen, dadurch wird der Code nur unleserlicher.

Verfasst: Freitag 5. Dezember 2008, 16:35
von Thuught
War nur ein Verzweiflungsakt :wink:

(Außerdem stellt sich mir die Frage, warum er auch bei list=[]
von "3 given" Argumenten redet.. ich meine wo kann ich mir
mal den Code von irgendwas anschauen, falls ich mal langeweile hab- oder
mal wieder ratlos bin? help(list) hilft nicht da nicht wirklich)

Verfasst: Freitag 5. Dezember 2008, 16:43
von DeJe
Wobei das sowieso etwas verwirrend ist.
Normalerweise sollten Klassen in Python doch in CapsCase bezeichnet werden. Die builtin-Klassen sind aber klein geschrieben (list, dict, object, ...). Da kann es schnell passieren diese Klassen zu überschreiben.

Verfasst: Freitag 5. Dezember 2008, 16:55
von Leonidas
Thuught hat geschrieben:Mir war nicht bewusst, dass man die Variabel "list" für ne Liste besser nicht vergeben sollte. :(
Man sollte generell keine Builtins überschreiben, dann spart man sich viele Probleme.

Verfasst: Freitag 5. Dezember 2008, 17:01
von derdon
DeJe hat geschrieben:Wobei das sowieso etwas verwirrend ist.
Normalerweise sollten Klassen in Python doch in CapsCase bezeichnet werden. Die builtin-Klassen sind aber klein geschrieben (list, dict, object, ...). Da kann es schnell passieren diese Klassen zu überschreiben.
Das liegt daran, dass int, str, list etc. sogenannte Factory Functions sind. Vor Python 2.2 waren sie Funktionen (built-in functions) und keine Klassen. Aus Kompatibilitätsgründen werden diese Klassen immer noch klein geschrieben.

Verfasst: Freitag 5. Dezember 2008, 17:02
von Leonidas
Und ``set`` ist aus Konsistenzgründen klein geschrieben. Früher wo es ein eigenes Modul war, war die Klasse großgeschrieben.

Verfasst: Freitag 5. Dezember 2008, 17:40
von DeJe
Dachte ich mir schon das das "historische" Gründe hat. ;)
Für einen Einsteiger ist es aber eben nicht ganz einfach bzw. z.B. 'list' als Bezeichner für eine Liste ist schnell gewählt, zunächst ohne böse Überraschung...den Fehler habe ich ja auch gemacht. ;)
Mittlerweile vergewissere ich mich in PyCrust ob ich (mit einem Bezeichner) nicht zufällig ein builtin erwische. :D