Seite 1 von 1
					
				Attribut als default-Parameter in Klassenmethode?
				Verfasst: Dienstag 23. August 2005, 15:27
				von N317V
				Hi, zusammen!
Man kann ja in Python bei einer Funktions- bzw. Methodendefinition für einen Parameter einen default-Wert definieren. Aber
Code: Alles auswählen
class foo:
    
    def __init__(self):
        self.irgendwas = 'dingsbums'
    def methodeEins(self, parameter=self.irgendwas):
        sonstiger Code
bringt mir den Fehler "NameError: name 'self' is not defined". Irgendwer ne Idee, was da falsch ist oder wie man das lösen kann?
TIA
Greetings!
N317V
 
			 
			
					
				
				Verfasst: Dienstag 23. August 2005, 15:33
				von jens
				Vielleicht nicht ganz was du willst:
Code: Alles auswählen
class foo:
    irgendwas = 'dingsbums'
    def methodeEins(self, parameter=irgendwas):
        print parameter
 
			 
			
					
				
				Verfasst: Dienstag 23. August 2005, 15:41
				von N317V
				Lösung hab ich jetzt doch noch schnell gefunden:
Code: Alles auswählen
def methodeEins(self, parameter=None):
    if not parameter:
        parameter=self.irgendwas
Nicht unbedingt der Bringer, aber immerhin gehts. Trotzdem versteh ich nicht so ganz, warum das andere nicht funktioniert. Das hielte ich für wesentlich eleganter.
 
			 
			
					
				
				Verfasst: Dienstag 23. August 2005, 15:44
				von mawe
				Hi!
Deine Methode etwas abgewandelt:
Code: Alles auswählen
In [1]: class Foo:
   ...:     def __init__(self):
   ...:         self.var = "blabla"
   ...:     def methode(self, parameter=None):
   ...:         bla = parameter or self.var
   ...:         print bla
   ...:
In [2]: f = Foo()
In [3]: f.methode()
blabla
In [4]: f.methode("gaga")
gaga
Gruß, mawe
 
			 
			
					
				
				Verfasst: Dienstag 23. August 2005, 16:02
				von N317V
				Auf jeden Fall schon mal Danke Euch beiden für die superschnelle Hilfe. Hat noch jemand ne Erklärung dafür, warum self nicht definiert ist? Ist doch auch der erste Parameter.
			 
			
					
				
				Verfasst: Dienstag 23. August 2005, 18:45
				von henning
				Ich nehme mal an, dass die Parameter erst im Funktionsrumpf als definiert gelten, wenn die Parameterliste angearbeitet ist.
Die default-Parameter-Zuweisung ist ja aber innerhalb der Parameterliste, deshalb ist self zu dem Zeitpunkt noch nicht definiert.
Das muss auch so sein, denn wenn ich folgendes habe:
Code: Alles auswählen
def foo(a, b, c=a.lower()):
  print a, b, c
d = {
 "a": "HALLO",
 "b": "blah",
 "c": 34
}
foo(**d)
dann 
kann dies nicht funktionieren, da ja nicht klar ist, in welcher Reihenfolge die keyowrd-werte aus dem dictionary geholt werden! (Elemente in einem Dictonary haben keine vorhersagbare Reihenfolge, zumindest konzeptionell)
PS: Man könnte eventuell einwenden, dass die keywords in Reihenfolge der Parameterliste raus geholt werden.
Fällt mir auch kein gutes Gegenargument zu ein, aber vielleicht veranschaulicht es das Dilemma trotzdem ein wenig.
 
			 
			
					
				
				Verfasst: Dienstag 23. August 2005, 22:08
				von BlackJack
				mawe hat geschrieben:Hi!
Deine Methode etwas abgewandelt:
Code: Alles auswählen
In [1]: class Foo:
   ...:     def __init__(self):
   ...:         self.var = "blabla"
   ...:     def methode(self, parameter=None):
   ...:         bla = parameter or self.var
   ...:         print bla
 
Ich würde nach Möglichkeit immer mit ``if`` auf ``is not None`` prüfen wenn man sich nicht ganz sicher ist, das nie ein Wert übergeben werden können soll, der "falsch" ist.  Da oben kann man `parameter` zum Beispiel nicht explizit auf eine leere Zeichenkette setzen.  Oder bei numerischen Werten schliesst man die 0 aus usw.
 
			 
			
					
				
				Verfasst: Mittwoch 24. August 2005, 06:47
				von jens
				Ich würde es auf lieber mit 
if machen, weil's einfacher zu verstehen ist... Die 
or Variante ist mir zu abgefahren, auch wenns schön klein ist 

 
			 
			
					
				
				Verfasst: Mittwoch 24. August 2005, 09:15
				von N317V
				Ich find die or-Variante voll geil; sehr pythonic  

 Und ich bin mir auch ganz sicher, dass da kein Wert übergeben werden soll, der False ergibt.
@henning: Dein Code-Beispiel leuchtet mir ein. Warum aber self an jede Methode der Klasse übergeben werden 
muss, andererseits aber zu dem Zeitpunkt nicht definiert ist, ist mir schleierhaft. Zumal ich diese Art der Vorbelegung für am sinnvollsten halte.
 
			 
			
					
				
				Verfasst: Mittwoch 24. August 2005, 09:52
				von Gast
				Das mit dem self ist eigentlich ganz logisch, wenn man mal
kurz vergisst, dass die Funktionen zu einem Objekt gehören.
An und für sich sind Funktionen, die in einer Klasse definiert werden
ja erstmal Klassenvariablen die zufällig den Typ Funktion haben.
Die gibts aber nur einmal pro Klasse, daher wissen sie nichts von einer Instanz (also dem Objekt der Klasse)!
Deswegen 
muss man self als Parameter entgegennehmen, damit man Zugriff auf das Objekt hat.
Wenn man folgendes hat:
Code: Alles auswählen
class Klasse:
  def func(self, a, b):
     self.blah = "foo"
k = Klasse()
Dann ist
Nur eine andere Schreibweise
(also wenn an so will "sntactic sugar") für
 
			 
			
					
				
				Verfasst: Mittwoch 24. August 2005, 09:54
				von henning
				Das letzte Posting ist von mir, war nicht eingeloggt.
			 
			
					
				
				Verfasst: Mittwoch 24. August 2005, 10:04
				von N317V
				@henning:
Heißt das, ich rufe eigentlich die Klasse auf, "starte" eine Funktion und übergebe ihr die Instanz und weitere Parameter? Puh! Ganz schön wirr.
Aber selbst wenn: wieso kann ich die Instanz übergeben, eine der Instanz bei deren Erzeugung zugewiesenes Attribut jedoch nicht. Das macht doch keinen Sinn.
			 
			
					
				
				Verfasst: Mittwoch 24. August 2005, 10:06
				von jens
				Anonymous hat geschrieben:Nur eine andere Schreibweise
(also wenn an so will "sntactic sugar") für
 
Das geht so allerdings nicht! So funktionierts:
 
			 
			
					
				
				Verfasst: Mittwoch 24. August 2005, 10:18
				von henning
				Also ich hatte mein Beispiel nicht getestet, aber was du schreibst wundert mich, weil Klasse() doch auch wieder ein Objekt ist, da müssten der Funktion insgesamt 4 Parameter übergeben werden, oder?!
N317V:
Nein, eigentlich ganz logisch, man ists nur nicht geöhnt von anderen OO-Sprachen ,-)
Ausserdem kannst du auch ein attribut der instanz übergeben:
Code: Alles auswählen
class Klasse:
  def __init__(self):
     self.x = 45
     self.y = 36
  def func(self, a, b):
     return self.y + a + b;
k = Klasse()
k.func(k.x, 7)
self ist bloß innerhalb der Parameterliste der Funktion nicht definiert!
 
			 
			
					
				
				Verfasst: Mittwoch 24. August 2005, 10:32
				von mawe
				henning hat geschrieben:
aber was du schreibst wundert mich, weil Klasse() doch auch wieder ein Objekt ist, da müssten der Funktion insgesamt 4 Parameter übergeben werden, oder?! 
Richtig, wie man auch an der Fehlermeldung sieht die man erhält 
Klasse.func(k, 3, 4) stimmt schon.
 
			 
			
					
				
				Verfasst: Mittwoch 24. August 2005, 10:37
				von jens
				Halt. In eurem Fall wird bei 
k.func(k.x, 7) die Klassenvariable 'x'  mitgeschickt. Das geht natürlich nicht, wenn es 
k nicht gibt 
Schauen wir uns mal folgende Klasse an:
Code: Alles auswählen
class foo:
    irgendwas = 'dingsbums'
    def methodeEins(self, parameter=irgendwas):
        print parameter
Hierbei geht der "direkte" Aufruf schon so: 
foo().methodeEins("jo") aber nicht so: 
foo.methodeEins("jo") 
			 
			
					
				
				Verfasst: Mittwoch 24. August 2005, 10:44
				von mawe
				jens, bitte lies Dir noch mal den Beitrag von henning und Deine Antwort darauf durch. Dort ist nämlich mit 
k = Klasse() längst eine Instanz erzeugt 

 
			 
			
					
				
				Verfasst: Mittwoch 24. August 2005, 10:46
				von jens
				Ups  

 Jetzt verstehe ich erst wie das gemeint war  
