Selbsterstellte Listklasse wirft TypeError

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Thuught
User
Beiträge: 28
Registriert: Mittwoch 3. Dezember 2008, 12:19

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?
BlackJack

Hm, kann ich nicht nachvollziehen:

Code: Alles auswählen

In [204]: class Vektoren(list):
   .....:     pass
   .....:
Zap
User
Beiträge: 533
Registriert: Freitag 13. Oktober 2006, 10:56

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[]
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

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
Thuught
User
Beiträge: 28
Registriert: Mittwoch 3. Dezember 2008, 12:19

Mein Programm heißt Active(state)python 2.6 und ich benutze die pywin32extension built 2.11.
Ist das zu empfehlen?
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

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).
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

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)
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Thuught
User
Beiträge: 28
Registriert: Mittwoch 3. Dezember 2008, 12:19

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.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

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?
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

@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'>
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

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.
Thuught
User
Beiträge: 28
Registriert: Mittwoch 3. Dezember 2008, 12:19

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)
DeJe
User
Beiträge: 39
Registriert: Sonntag 23. November 2008, 19:38

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.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

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.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Und ``set`` ist aus Konsistenzgründen klein geschrieben. Früher wo es ein eigenes Modul war, war die Klasse großgeschrieben.
Zuletzt geändert von Leonidas am Freitag 5. Dezember 2008, 17:49, insgesamt 1-mal geändert.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
DeJe
User
Beiträge: 39
Registriert: Sonntag 23. November 2008, 19:38

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
Antworten