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