Kellerspeicher und umgekehrte Polnische Notation

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Sonntag 23. November 2008, 16:45

Leonidas hat geschrieben:Was soll das soll das ``k`` vor den Namen?
Vielleicht hast du gerade einen KDE-Entwickler enttarnt :D
Benutzeravatar
jonas
User
Beiträge: 156
Registriert: Dienstag 9. September 2008, 21:03

Sonntag 23. November 2008, 16:46

hi,
@Leonidas:
Das `k` vor den Namen steht für "Keller-"
Ich wäre dir verbunden wenn du den Hinweis auf
die Namespaces nochmal in diesem Zusammenhang
erläutern könntest, kapier ich nämlich nicht :?:
Wenn man den Kellerspeicher benutzt benutzt man
doch nur "alphabet":

Code: Alles auswählen

IMkeller = Kellerspeicher(alphabet=[1,2,3,4])
MfG Jonas :D
DasIch
User
Beiträge: 2465
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Sonntag 23. November 2008, 16:47

@jonas Die Aufgabenstellung löst dass wohl nicht so ganz und die Underscores bei push und pop gehören da nicht hin. Wenn überhaupt verwendet man zwei vor dem Namen aber hier will man ja von außen darauf zugreifen.
Zu den namespaces kellerspeicher.kalphabet vs. kellerspeicher.alphabet was erscheint dir sinnvoller?

Sinnvoller ist es hier von list zu erben und append(, pop) zu überschreiben.
Benutzeravatar
jonas
User
Beiträge: 156
Registriert: Dienstag 9. September 2008, 21:03

Sonntag 23. November 2008, 16:51

Hi,
@DasIch:
Danke für die hilfreichen Anregungen zum Code.
Wann benutzt man den genau "Underscores"?
Erben von z.B. list werd ich mir nochmal ansehen.
:D

MfG Jonas
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Sonntag 23. November 2008, 16:53

jonas hat geschrieben:Das `k` vor den Namen steht für "Keller-"
Ich wäre dir verbunden wenn du den Hinweis auf
die Namespaces nochmal in diesem Zusammenhang
erläutern könntest, kapier ich nämlich nicht :?:
Ja, aber welchen Sinn haben die ``k``? Es ist schon klar, dass ``alphabet`` zu ``Kellerspeicher`` gehört, es ist ja ein Attribut der Klasse.

Du stimmst mir sicher zu, dass

Code: Alles auswählen

kellerspeicher = Kellerspeicher(['a'])
print kellerspeicher.kalphabet
irgendwie seltsam ist wenn ``kellerspeicher.alphabet`` genauso möglich wäre.

Außerdem hast du da ein Mutables Objekt in der Signatur, das solltest du lassen, denn damit kannst du dir erstaunlich abstruse Fehler einfangen. So wird die Liste nur einmal erstellt und behält ihre Inhalte (statt immer auf [] gesetzt zu werden) - sowas willst du mit hoher Sicherheit nicht haben.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
jonas
User
Beiträge: 156
Registriert: Dienstag 9. September 2008, 21:03

Sonntag 23. November 2008, 16:57

Hi,
@Leonidas:
Das

Code: Alles auswählen

print kellerspeicher.alphabet
komfortabler ist als

Code: Alles auswählen

print kellerspeicher.kalphabet
damit hast du Recht!
Aber das mit mutable object versteh ich noch nicht so ganz...
Meinst du meine Forensignatur?

MfG Jonas
DasIch
User
Beiträge: 2465
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Sonntag 23. November 2008, 17:04

Code: Alles auswählen

In [87]: def foo(bar=[]):
   ....:     return bar
   ....:

In [88]: a = foo()

In [89]: a.append('spam')

In [90]: foo()
Out[90]: ['spam']
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Sonntag 23. November 2008, 17:05

jonas hat geschrieben:Aber das mit mutable object versteh ich noch nicht so ganz...
Meinst du meine Forensignatur?
Nein, ich meine die Funktionssignatur von ``__init__``.

Beispiel wo sowas zu Problemen führt:

Code: Alles auswählen

>>> class K(object):
...   def __init__(self, args=[]):
...     args.append(7)
...     self.args = args
... 
>>> k1 = K([1, 2, 3])
>>> k2 = K()
>>> k1.args
[1, 2, 3, 7]
>>> k2.args
[7]
>>> k3 = K()
>>> k3.args
[7, 7]
Wie du siehst, bekommst du da ``[7, 7]`` wo du eher ``[7]`` erwartet hättest.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
BlackJack

Sonntag 23. November 2008, 17:52

@jonas: Die doppelten Unterstriche vor und nach dem Namen verwendet man, wenn man eine der "magischen" Methoden implementiert, die eine besondere Bedeutung in der Sprache haben. Zum Beispiel um ein Objekt iterierbar zu machen, Operatoren zu überladen, oder Indexzugriff zu ermöglichen.

Nachtrag: Mit dem Kelleralphabet ist der Kellerspeicher für die Aufgabe nicht brauchbar, oder soll man da wirklich alle Zahlen übergeben, mit denen man rechnen können soll!?

Das Du Fehler mit ``print`` ausgibst, statt Ausnahmen auszulösen und sogar vorhandene Ausnahmen auf diese Weise "verschluckst", ist auch äusserst ungünstig.

Wenn das Programm etwas mit dem Kellerspeicher anstellt, was nicht in Ordnung ist, dann möchte man wohl kaum, dass das Programm sagt, hey hier ist was dummes passiert, und dann einfach weiter macht, als wenn nichts gewesen wäre.
Benutzeravatar
jonas
User
Beiträge: 156
Registriert: Dienstag 9. September 2008, 21:03

Sonntag 23. November 2008, 18:43

Hi,
@Leonidas:
Danke für den für mich persönlich hilfreichen Beitrag.
So etwas, wie in deinem Beispiel zu sehen, wäre natürlich
denkbar schlecht.
@Blackjack:
Danke für die hilfreiche Aufklärung über die "magischen" Methoden.
Mit

Code: Alles auswählen

def irgendeinefunktion ():
    try:
        ## tuEtwas...
    except :
        print """Hallo es gab irgendeinen Error aber
                machen Sie sich mal keine Sorgen..."""
hast du natürlich Recht, auch das wäre denkbar ungünstig.
MfG Jonas :D
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Sonntag 23. November 2008, 18:57

Ein einzelner Underscrore steht für die Dinge, die nicht "öffentlich" sein sollen, also von außen nicht benutzt werden sollen. Das ist aber nur eine Konvention, es wird also nichts erzwungen. Beispielsweise ist ein solcher Einsatz denkbar wenn du eine Klasse erstellst, die eine API implementiert (add_thing, remove_thing, do_somethign_important ...), und dann eine spezialisiertere Klasse erstellst, die von dieser abgeleitet ist. Willst du dort für Ordnung sorgen und etwas in eine eigene Methode auslagern, (zb "_build_important_structure"), kannst / solltest du den Underscore benutzen.

Doppelte Underscores werden einerseits für die "magischen Methoden" verwendet, andererseits kann man damit Dinge vor einem direkten Zugriff "schützen", der von außerhalb erfolgt (auch wenn sie nicht wirklich geschützt sind, man kommt noch über Umwege dran). "Offiziell" wird das aber nur dazu benutzt, um dem Mangel an Schreibweisen in Bezug auf einen bestimmten Namen zu vermeiden.

Praktisch braucht man das nie, außer für magische Methoden.
Benutzeravatar
jonas
User
Beiträge: 156
Registriert: Dienstag 9. September 2008, 21:03

Sonntag 23. November 2008, 19:07

Hi.
@str1442:
str1442 hat geschrieben:[...]Beispielsweise ist ein solcher Einsatz denkbar wenn du eine Klasse erstellst, die eine API implementiert (add_thing, remove_thing, do_somethign_important ...), und dann eine spezialisiertere Klasse erstellst, die von dieser abgeleitet ist.[...]
Ist so eine spezialisierte Klasse z.B. Frog <=> Tkinter ?
MfG Jonas
DasIch
User
Beiträge: 2465
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Sonntag 23. November 2008, 19:11

jonas hat geschrieben:Ist so eine spezialisierte Klasse z.B. Frog <=> Tkinter ?
Nein, Frog ist ein gutes Beispiel um zu zeigen wie man soetwas missbrauchen kann um den Nutzer unnötig einzuschränken.
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Sonntag 23. November 2008, 19:14

Frog kenne ich nicht.

Aber zb sowas:

Code: Alles auswählen

class AbstractCls(object):
    def add(self):
         pass
    def request(self):
         pass

class Cls(AbstractCls):
    def add(self):
         # Wichtiger Code
    def _do_sth_for_add(self):
        # Mach irgendwas und nutze Instanzvariablen dazu.
Anwendung zb bei Objekten, die alle das gleiche Interface brauchen, aber nicht wissen
sollen, mit wem sie konkret agieren. Da ist "_do_sth_for_add" auch etwas, was diesem Objekt nicht bekannt ist. So kann man damit ganz banal verschiedene Parser für Dateitypen von einem "AbstractParser" ableiten, hoffe du verstehst das Prinzip.
Benutzeravatar
jonas
User
Beiträge: 156
Registriert: Dienstag 9. September 2008, 21:03

Sonntag 23. November 2008, 19:36

hi,
str1442 hat geschrieben:So kann man damit ganz banal verschiedene Parser für Dateitypen von einem "AbstractParser" ableiten, hoffe du verstehst das Prinzip.
Sorry aber nicht wirklich :oops:
MfG Jonas
Antworten