Seite 1 von 1

self erklären

Verfasst: Dienstag 1. Juni 2010, 13:25
von mzh
Hallo zusammen

Ich versuche einem Kollegen 'self' zu erklären. Dazu habe ich folgendes Programm geschrieben, dass den Witz dahinter m.E. illustriert.
Sind meine Kommentare im Programm zutreffend?

Code: Alles auswählen

#!/usr/bin/env python

class Machine:
    
    #Class Variable counts how many machines
    #have been created.
    #The value is the same for all objects
    #of this class.
    counter = 0 
    
    def __init__(self):
    
        #This is a short hand notation for
        #Machine.counter = Machine.counter + 1
        #Notice: no 'self'.
        Machine.counter += 1
    
        #This variable is an instance variable.
        #It is different for every object of
        #the class.
        self.id = Machine.counter
    
    def getID(self):
        #You need 'self' here to adress the
        #variable of the particular object
        #calling this method.
        return self.id
    
    def getCounter(self):
        #No 'self' here. You call the
        #variable of the class.
        return Machine.counter
    
if __name__ == '__main__':
    machine1 = Machine()
    machine2 = Machine()
    machine3 = Machine()
    
    #The value is different for all objects.
    print 'machine1.getID()', machine1.getID()
    print 'machine2.getID()', machine2.getID()
    print 'machine3.getID()', machine3.getID()
    
    print
    print
    
    #The value is the same for all objects.
    print 'machine1.getCounter()', machine1.getCounter()
    print 'machine2.getCounter()', machine2.getCounter()
    print 'machine3.getCounter()', machine3.getCounter()

Re: self erklären

Verfasst: Dienstag 1. Juni 2010, 13:37
von DasIch
Die get Methoden sind überflüssig, die Kommentare stimmen so.

Re: self erklären

Verfasst: Dienstag 1. Juni 2010, 13:54
von mzh
@DasIch: du meinst, man ruft die Variable direkt auf: print Machine.counter ? Danke für den Hinweis.

Re: self erklären

Verfasst: Dienstag 1. Juni 2010, 15:04
von /me
mzh hat geschrieben:@DasIch: du meinst, man ruft die Variable direkt auf: print Machine.counter ? Danke für den Hinweis.
Das gleiche gilt für

Code: Alles auswählen

print machine1.id
Getter und Setter stammen aus Bondage-Sprachen wie Java und sollten nur dann verwendet werden, wenn sie wirklich einen Mehrwert bieten.

Re: self erklären

Verfasst: Dienstag 1. Juni 2010, 19:20
von Darii
/me hat geschrieben:Getter und Setter stammen aus Bondage-Sprachen wie Java und sollten nur dann verwendet werden, wenn sie wirklich einen Mehrwert bieten.
So abwertend sollte man das nicht formulieren.

Dass man getter und setter in Python nicht braucht, liegt einzig und allein daran, dass es Properties gibt, die von außen nicht von einem normalen Attributzugriff zu unterscheiden sind. Oder anders aus gedrückt, man kann Instanzvariablen durch Properties ersetzen ohne die Schnittstelle nach außen zu ändern. Und das ist ein ziemlichen Alleinstellungsmerkmal von Python. Das geht auch in vielen nicht-„bondage“-Sprachen nicht.

Re: self erklären

Verfasst: Dienstag 1. Juni 2010, 20:43
von Leonidas
Darii hat geschrieben:
/me hat geschrieben:Und das ist ein ziemlichen Alleinstellungsmerkmal von Python.
Naja, wenn ich so überlege fällt mir recht bald C# und Scala ein. Also so selten ist das ja nicht.

Re: self erklären

Verfasst: Dienstag 1. Juni 2010, 22:11
von Darii
Leonidas hat geschrieben:
Darii hat geschrieben:
/me hat geschrieben:Und das ist ein ziemlichen Alleinstellungsmerkmal von Python.
Naja, wenn ich so überlege fällt mir recht bald C# und Scala ein. Also so selten ist das ja nicht.
Die Properties von C# werden vom Compiler in Methodenaufrufe umgeschrieben, d.h. das ganze funktioniert nur, so lange du den Quellcode zur Verfügung hast und du das neu kompilieren kannst. Kompatibilität auf Bytecodeebene ist aber nicht gegeben. Anders als bei Python. Bei Scala wird das nicht anders laufen.

Re: self erklären

Verfasst: Freitag 11. Juni 2010, 19:05
von pillmuncher
Darii hat geschrieben:
/me hat geschrieben:...Bondage-Sprachen...
So abwertend sollte man das nicht formulieren.
Mir gefällt's :mrgreen:
Darii hat geschrieben:Dass man getter und setter in Python nicht braucht, liegt einzig und allein daran, dass es Properties gibt, die von außen nicht von einem normalen Attributzugriff zu unterscheiden sind. Oder anders aus gedrückt, man kann Instanzvariablen durch Properties ersetzen ohne die Schnittstelle nach außen zu ändern. Und das ist ein ziemlichen Alleinstellungsmerkmal von Python.
Bei Eiffel gab's das AFAIK zuerst.

Gruß,
Mick.

Re: self erklären

Verfasst: Freitag 11. Juni 2010, 21:09
von Darii
pillmuncher hat geschrieben:Bei Eiffel gab's das AFAIK zuerst.
Nein, wenn ich das richtig verstehe, funktioniert das da genauso wie in C#. Die Attributzugriffe werden vom Compiler in Methodenaufrufe umgeschrieben. Allerdings hat man da wohl das Java-Problem nicht, da man überhaupt nicht die Möglichkeit hat, direkt auf ein Attribut zuzugreifen.

Re: self erklären

Verfasst: Samstag 12. Juni 2010, 13:56
von sma
Es gibt Sprachen, in den gibt es keine von außen sichtbaren Variablen wie z.B. Smalltalk. Dort hat man immer Methoden, die einfach wie Properties aussehen. In Smalltalk-78 konnte man `foo bar = foo bar + 1` schreiben, was dann das "Property" `bar` des Objekts `foo` erhört. Ab Smalltalk-80 ist das zu `foo bar: foo bar + 1` geworden, weil man den komischen Methodennamen `bar =` (mit optionalem Leerzeichen) nicht haben wollte. Was sich hinter `bar` und `bar:` verbirgt und ob das einfach nur Getter und Setter sind oder komplexe Berechnungen, sieht man nicht und kann man ohne Rekompilation des restlichen Programms ändern. Und das war mehr als 10 Jahre vor Python.

Stefan

Re: self erklären

Verfasst: Samstag 12. Juni 2010, 17:52
von Darii
Darum gings ja auch gar nicht. Wenn ich sowieso nur Methoden zur Verfügung habe, kann man sie natürlich trivialer Weise, ohne den restlichen Teil des Programm zu ändern, durch Methoden mit derselben Signatur ersetzen kann. Das geht sogar bei C++(wenn da nicht gerade irgendwas geinlined wurde).

Mir ging es darum, dass Properties in Python dieselbe (öffentliche) Schnittstelle nach außen haben, wie normale Attribute. Und das ist afaik bei keiner anderen Sprache so. Bei Smalltalk gibt es keine öffentliche Schnittstelle zu Instanzvariablen, also stellt sie dich Frage gar nicht erst.

Wobei man natürlich argumentieren könnte, dass Python auch keinen direkten Zugriff auf Instanzvariablen bietet, dann läuft es im Endeffekt auf selbe hinaus, bloß dass Python mit noch mehr CPU-Zyklen die Wohnung heizt, als Smalltalk.

Re: self erklären

Verfasst: Samstag 12. Juni 2010, 18:12
von lunar
@Darii: Scala erzeugt meines Wissens implizit Zugriffsmethoden für öffentliche Attribute. Um die Zugriffsmethoden zu erweitern, kann man also nachträglich das Attribut umbenennen und die Zugriffsmethoden manuell implementieren, ohne dass sich die öffentliche Schnittstelle (sowohl binär als auch im Quelltext) dadurch ändert. Bei Scala sind also faktisch alle Attribute Eigenschaften.

Allerdings würde ich nicht sagen, dass Eigenschaften in Python dieselbe öffentliche Schnittstelle wie Eigenschaften haben. Schließlich unterscheiden sich Eigenschaften als Deskriptoren doch deutlich von normalen Attributen. Nur ist das eben vollkommen egal, weil Zugriffe immer erst zur Laufzeit aufgelöst werden.

Re: self erklären

Verfasst: Samstag 12. Juni 2010, 20:17
von str1442
In Scala werden Methodenpaare der Form type T; def <name>: T; def <name>_=(newT: T): Unit als Properties erkannt - ich glaube nicht, dass für andere Formen eine solche Behandlung stattfindet (oder gar generell):

Code: Alles auswählen

scala> class A(x: Int) {
     | private var _internal_x: Int = x
     | def public_x: Int = _internal_x * 2
     | def public_x_=(newX: Int): Unit = _internal_x = newX / 2
     | }
defined class A

scala> var a = new A(54)
a: A = A@3e97cd

scala> a.public_x
res0: Int = 108

scala> a.public_x = 100

scala> a.public_x
res1: Int = 100

Re: self erklären

Verfasst: Samstag 12. Juni 2010, 22:39
von Darii
lunar hat geschrieben:@Darii: Scala erzeugt meines Wissens implizit Zugriffsmethoden für öffentliche Attribute.
Dann ist das Problem nicht existent.
Allerdings würde ich nicht sagen, dass Eigenschaften in Python dieselbe öffentliche Schnittstelle wie Eigenschaften haben. Schließlich unterscheiden sich Eigenschaften als Deskriptoren doch deutlich von normalen Attributen. Nur ist das eben vollkommen egal, weil Zugriffe immer erst zur Laufzeit aufgelöst werden.
Die öffentliche Schnittstelle für Attributzugriffe ist getattr, setattr, getattr bzw. die Äquivalente im Bytecode. Dadurch sind Attribute und Deskriptoren von außen ununterscheidbar.

Re: self erklären

Verfasst: Sonntag 13. Juni 2010, 11:02
von lunar
@str1442: In Scala wird nach Spezifikation jede Variablendeklaration mittels "var" in Zugriffsmethoden übersetzt:
A variable declaration var x : T is equivalent to declarations of a getter function x
and a setter function x _=, defined as follows:
def x : T
def x _= ( y : T ): Unit
Eigenschaften im eigentlichen Sinne kennt Scala gar nicht, da es auch keine Operatoren gibt. Jeder Operator ist in Scala nichts anderes als ein Methodenaufruf (syntaktisch gibt es nur keinen Unterschied). Daher muss Scala jede Variablendeklaration wie beschrieben übersetzen, da die Zuweisung an die Variable sonst schlichtweg nicht definiert wäre.

@Darii: So gesehen hast Du natürlich recht.