Methode nimmt den Rest der Klasse mit

8 views
Skip to first unread message

Matthias Müller-Reineke

unread,
Oct 26, 2010, 4:57:01 PM10/26/10
to hamburg-p...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Liebe PyUG,

was gibt dieses aus?


#!/usr/bin/env python

class S(object):
def __init__(self, override=None):
if override:
o = override()
self.__dict__['name'] = getattr(o, 'name')

def name(self):
print self.xy, self.__class__ #.__name__


class Override(S):
xy=5


S(Override).name()


Wieso wird xy aus der Override-Instanz in die S-Instanz �bertragen?
Die Methode name scheint sich die ganze Instanz mitzunehmen.


Mit freundlichen Gr��en
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkzHQJ0ACgkQ1YBorh7//Or+agCdGAzB9/fU0hjghpBYkWgOpARs
hosAniGUDwDDj9K33YN2WmqkgVWhTAiC
=c0ZQ
-----END PGP SIGNATURE-----

abpy...@arcor.de

unread,
Oct 26, 2010, 6:56:04 PM10/26/10
to hamburg-p...@googlegroups.com


----- Original Nachricht ----
Von: Matthias Müller-Reineke <mueller-rei...@alice-dsl.de>
An: hamburg-p...@googlegroups.com
Datum: 26.10.2010 22:57
Betreff: [hh-pythoneers:224] Methode nimmt den Rest der Klasse mit

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Liebe PyUG,
>
> was gibt dieses aus?
>
>
> #!/usr/bin/env python
>
> class S(object):
> def __init__(self, override=None):
> if override:
> o = override()
> self.__dict__['name'] = getattr(o, 'name')
>
> def name(self):
> print self.xy, self.__class__ #.__name__
>
>
> class Override(S):
> xy=5
>
>
> S(Override).name()
>
>

> Wieso wird xy aus der Override-Instanz in die S-Instanz übertragen?


> Die Methode name scheint sich die ganze Instanz mitzunehmen.

Ähm, weil es so programmiert wurde? ;-) ;-) Interessanter als die Methode name scheint mir __init__ zu sein. Da wird eine instanz von, was auch immer als override übergeben wird, erzeugt und danach das name von der S-instanz auf das name dieser override-instanz umgebogen. Damit ist dann die name-Methode aus der S-Klasse tot und es wird nur das name von der override-Instanz benutzt.

Ich habe das Beispiel mal etwas erweitert:

#!/usr/bin/env python

class S2(object):
def __init__(self, override=None):
print 'id:',id(self),self.__class__ #.__name__


if override:
o = override()
self.__dict__['name'] = getattr(o, 'name')

def name(self):
print id(self),self.xy, self.__class__ #.__name__


class Override2(S2):
xy=5


S2(Override2).name()

-------------------------------------------

Alternativ klärt vielleicht auch schon:

was = S(Override)
help(was.name)

alle offenen Fragen.


Grüße,
Andreas

Rainer Mansfeld

unread,
Oct 27, 2010, 6:17:41 AM10/27/10
to hamburg-p...@googlegroups.com
Am 26. Oktober 2010 22:57 schrieb Matthias Müller-Reineke
<mueller-rei...@alice-dsl.de>:

> Liebe PyUG,
>
> was gibt dieses aus?
>
>
> #!/usr/bin/env python
>
> class S(object):
>    def __init__(self, override=None):
>        if override:
>            o = override()
>            self.__dict__['name'] = getattr(o, 'name')
>
>    def name(self):
>        print self.xy, self.__class__ #.__name__
>
>
> class Override(S):
>    xy=5
>
>
> S(Override).name()
>
>

> Wieso wird xy aus der Override-Instanz in die S-Instanz übertragen?


> Die Methode name scheint sich die ganze Instanz mitzunehmen.

Hallo Matthias,

die Methode 'name' der Klasse S wird in 'S.__init__' mit der von S
geerbten 'name'-Methode der Klasse 'Override' überschrieben.

Wenn man die (ohnehin fragwürdige) "abgeleitete Klasse überschreibt
Basis-Klasse Konstruktion" und den anderen Schnickschnack mal
weglässt, wird aus dem Ganzen:

class A(object):
def __init__(self):
self.name = B().name

class B(object):
xy = 5

def name(self):
print self.xy

A().name()

'A.name' wird also eine an eine 'B'-Instanz gebundene Methode
zugewiesen und druckt deshalb 'B.xy'.

Viele Grüße

Rainer

Matthias Müller-Reineke

unread,
Oct 27, 2010, 1:56:32 PM10/27/10
to hamburg-p...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Am 26.10.2010 22:57, schrieb Matthias M�ller-Reineke:

> class S(object):
> def __init__(self, override=None):
> if override:
> o = override()

Hier wird ein "Method Object" (= Funktion + Daten des Objekts) extrahiert.
Siehe http://docs.python.org/tutorial/classes.html#method-objects

> self.__dict__['name'] = getattr(o, 'name')
>
> def name(self):
> print self.xy, self.__class__ #.__name__
>
>
> class Override(S):
> xy=5
>

Und hier wird o.name mit "o als self" aufgerufen:
> S(Override).name()

Das ist also kein Bug sondern ein in
http://docs.python.org/tutorial/classes.html#method-objects
beschriebenes Feature.


Mit freundlichen Gr��en
Matthias


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkzIZ9AACgkQ1YBorh7//OoNTQCfVYowYSBtd4NHI2mSmRz1sFB0
FoYAnj+a6VziNs0qdTF8sqBzIMC4v6zA
=zLEW
-----END PGP SIGNATURE-----

Rainer Mansfeld

unread,
Oct 28, 2010, 5:21:50 AM10/28/10
to hamburg-p...@googlegroups.com
Am 27. Oktober 2010 19:56 schrieb Matthias Müller-Reineke
<mueller-rei...@alice-dsl.de>:

>
> Am 26.10.2010 22:57, schrieb Matthias Müller-Reineke:
>
>> class S(object):
>>     def __init__(self, override=None):
>>         if override:
>>             o = override()
>
> Hier wird ein "Method Object" (= Funktion + Daten des Objekts) extrahiert.
> Siehe http://docs.python.org/tutorial/classes.html#method-objects

Nein, hier wird eine ganz normale Instanz der Klasse Override erzeugt.

"S(Override)" instantiiert ein neues Objekt der Klasse S.
Dabei wird die Klasse Override als Parameter override an die __init__-Methode
von S übergeben.
"o = override()" bedeutet also in diesem Fall nichts anderes als "o =
Override()"
und das ist eine gewöhnliche Instantiierung und hat mit Method-Objects
nix zu tun.


>>             self.__dict__['name'] = getattr(o, 'name')
>>
>>     def name(self):
>>         print self.xy, self.__class__ #.__name__
>>
>>
>> class Override(S):
>>     xy=5
>>
> Und hier wird o.name mit "o als self" aufgerufen:
>> S(Override).name()
>
> Das ist also kein Bug sondern ein in
> http://docs.python.org/tutorial/classes.html#method-objects
> beschriebenes Feature.
>
>

> Mit freundlichen Grüßen
> Matthias

Viele Grüße

Rainer

Reply all
Reply to author
Forward
0 new messages