Verständnisproblem bei Magic methods

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
KlausS
User
Beiträge: 40
Registriert: Donnerstag 24. Januar 2008, 08:52
Wohnort: Leverkusen

Hallo Liste,

bei dem folgenden Beispiel aus "Beginning Python" (Seite 186) von Magnus Lie Hetland soll nach Vorgabe bei der ersten counter-Abfrage
0 und bei der zweiten 2 herauskommen.

Code: Alles auswählen

In [41]: class CounterList(list):
   ....:     def __init__(self, *args):
   ....:         super(CounterList, self).__init__(*args)
   ....:         self.counter = 0
   ....:     def __getitem__(self, index):
   ....:         self.counter += 1
   ....:         return super(CounterList, self).__getitem__(index)
   ....: 

In [42]: cl = CounterList(range(10))

In [43]: cl
Out[43]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [44]: cl.reverse()

In [45]: cl
Out[45]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

In [46]: del cl[3:6]

In [47]: cl
Out[47]: [9, 8, 7, 3, 2, 1, 0]

In [48]: cl.counter
Out[48]: 3

In [49]: cl[4] + cl[2]
Out[49]: 9

In [50]: cl.counter
Out[50]: 5
Bei mir kommt allerdings 3 und 5 heraus. Bei der Ausgabe eines Teststrings kann ich sehen, das die Methode __getitem__ bei jedem cl einmal und bei cl[4] + cl[2] zweimal aufgerufen wird. Somit stimmen die angezeigten Daten.
Kann mir jemand verraten, wieso das abweichende Ergebnis herauskommt. Oder ist das vielleicht nur ein Fehler im Buch? Ich nutzte Python 2.6.1

Gruß

Klaus
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Das koennte ein Nebeneffekt von iPython sein, hast du den Code schonmal in einer anderen Shell ausprobiert?
KlausS
User
Beiträge: 40
Registriert: Donnerstag 24. Januar 2008, 08:52
Wohnort: Leverkusen

Hallo DasIch,

ich habe es jetzt mal in der normalen Python-Shell versucht. Leider habe ich das Ergebnis verschlimmbessert:

Code: Alles auswählen

[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> class CounterList(list):
...     def __init___(self, *args):
...         super(CounterList, self).__init__(*args)
...         self.counter = 0
...     def __getitem__(self, index):
...         self.counter += 1
...         return super(CounterList, self).__getitem__(index)
... 
>>> cl = CounterList(range(10))
>>> cl
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> cl.reverse()
>>> cl
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> del cl[3:6]
>>> cl
[9, 8, 7, 3, 2, 1, 0]
>>> cl.counter
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'CounterList' object has no attribute 'counter'
>>> 
Scheinbar habe ich jetzt auch noch Tomaten auf den Augen, weil ich den Fehler nicht finden kann. Ich sollte wohl besser das Buch für heute zur Seite legen. :(

Klaus
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Strategisch verteilte Ausgaben mit print() helfen bei der Fehlersuche. Hier kannst du feststellen, dass __init___ niemals aufgerufen wird. Der Grund ist einfach: Du hast einen Unterstrich zu viel verwendet.
KlausS
User
Beiträge: 40
Registriert: Donnerstag 24. Januar 2008, 08:52
Wohnort: Leverkusen

@/me:
:oops: Ich habe es ja schon vermutet, Tomaten auf den Augen.
@DasIch:
Du hast recht. Mit der normalen Python-Shell komme ich zu dem gleichen Ergebnis wie in der Buchvorlage. Ist das ein IPython-typisches Problem, das darauf hindeutet, besser die Finger von IPython zu lassen?

Gruß

Klaus
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Optimal waere eine Shell zu haben die den Code in einem seperaten Interpreter ausfuehrt, afaik arbeiten die bpython Leute daran haben es aber auch nicht. Prinzipiell ist es aber kein so grosses Problem, ueblicherweise probiert man ja nur kleine Sachen in der Shell aus.

Behalt einfach im Hinterkopf dass die Shell auf Objekte irgendwie lesend zugreifen kann und Referenzen auf Ausgaben haelt und im Zweifel fuer den Code ohne Shell aus.
KlausS
User
Beiträge: 40
Registriert: Donnerstag 24. Januar 2008, 08:52
Wohnort: Leverkusen

Hallo DasIch,

ich werde es berücksichtigen. Danke für deine Mühe.

Gruß

Klaus
Antworten