[Python-de] Subclassing int

Gerhard Häring gh at ghaering.de
Mon May 26 21:09:53 EDT 2003


Gerson Kurz wrote:
> Ich habe heute mal versucht, eine Klasse, die bisher so aussah:
> 
> class bisher:
>     def __init__(self):
>         self.wert = 123
> 
>     ... (+ n Methoden, die self.wert verändern) ...
> 
> 
> durch eine Klasse
> 
> class neu(int):
> 
> zu ersetzen. Das ganze habe ich ziemlich schnell aufgegeben, mit ein bisserl
> Enttäuschung. Schluchz. Sieh her:
> 
> class neu(int):
>     def __init__(self, value):
>         int.__init__(self, 2)
> 
> a = neu(1)
> 
> Preisfrage: Was macht "print a" ? Es gibt 1 aus! (Die "Dokumentation"
> ("Whats New in Python 2.2.txt") ist ein bisserl arg mager, IMHO))

Ich kenn nur http://python.org/2.2.3/descrintro.html

> Des weiteren: Ich kann den Wert meines ints nicht ändern! Nun ist mir ja
> bekannt, daß int immutable ist, aber sieh dir mal folgendes an:
> 
> class bisher:
>     def __init__(self):
>         self.wert = 123
>         print "ID im Konstruktor:", id(self.wert)
> 
>     def assign(self, value):
>         self.value = value
>         print "ID nach assign:", id(self.wert)
> 
> a = bisher()
> a.assign(60)
> 
> ...
> ID im Konstruktor: 7627404
> ID nach assign:    7627404
> 
> Meine laienhafte Vermutung: die Runtime nimmt automatisch das gleiche Objekt
> wieder her, 

Warum sollte sich id() ändern? Dass es sich *nicht* ändert, ist ja genau 
die Definition von Objektidentität:

[http://python.org/doc/current/ref/objects.html]
"""
[...] Every object has an identity, a type and a value. An object's 
identity never changes once it has been created; you may think of it as 
the object's address in memory. [...]
"""

> oder es gibt so einen Objectcache (dunkel wabert derartiges in
> den zugegebenermaßen leeren Hallen meines Erinnerungsvermögens).

Es gibt einen "Cache" für ints. Das ist aber auch schon alles:

http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/python/python/dist/src/Objects/intobject.c?rev=HEAD&content-type=text/vnd.viewcvs-markup

#v+
#ifndef NSMALLPOSINTS
#define NSMALLPOSINTS		100
#endif
#ifndef NSMALLNEGINTS
#define NSMALLNEGINTS		5
#endif
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
/* References to small integers are saved in this array so that they
    can be shared.
    The integers that are saved are those in the range
    -NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).
*/
static PyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
#endif
#v-

> Das ganze kann ich aber mit meiner "neu"-Klasse nicht machen. Selbst
> todesmutige Versuche wie
> 
> class neu(int):
>     def __init__(self, value):
>         int.__init__(self, 2)
> 
>     def assign(self, value):
>         self = neu(value)
> 
> a = neu(1)
> a.assign(3)
> 
> scheitern. Schade aber toll, oder?

Zwei Fehler. Erstens musst du in dem Fall __new__ überladen, nicht 
__init__. Zweitens ist "self = neu(value)" ein NOP (oder wie auch immer 
das in 68k-Assembler statt x86- heisst ;-). Der Istgleich-Operator 
bindet nur Objekte an Namen, ändert aber *niemals* bestehende Objekte. 
Somit kann man in Python zwar fast alle Schweinereien wie in C++ machen, 
aber eben nicht ganz alle :-P

lambda-ly yours,

-- Gerhard





More information about the Python-de mailing list