besser so oder so?

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.
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hi rolgal,

da wirfst Du jetzt 2 Sachen durcheinander.
Test.site_vars ist ein veränderbares Attribut. Wenn Du es noch mehr schützen willst mach es so:

Code: Alles auswählen

#!/usr/local/bin/python


class Test(object):
   
    __slots__=['__site_vars']
    def site_vars(self):
        return self.__site_vars
    site_vars = property(site_vars, doc="readonly")

    base_vars={'a' : '1',
               'b' : '2',
               'c' : '3',
               'd' : ''}
    def __init__(self, **kw):
            self.__site_vars=self.base_vars.copy()
            self.__site_vars.update(kw)
    def __str__(self):
            site=str(self.site_vars.values())
            return site 
Natürlich kannst Du das Dictionary self.site_vars immer noch manipulieren, ist ja ein Mutable Object. Aber du kannst jetzt sitevars keinen Wert direkt zuweisen.


Gruß

Dookie
Gast

hi

bevor ich mich auf dein neues bsp. stürze:

Code: Alles auswählen

__slots__
sollte instanzen davor schützen, dass ihnen keinen neue attribute zugewiesen werden können zur laufzeit, bzw. die werte nicht verändert werden können.

es steht die frage an, wie gut und sinnvoll das implementiert wurde, wenn ich über die klasse die instanz erreichen kann.

denn: die klasse muss ich ja immer kennen, oder?

mfg

rolgal[/code][/quote]
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Bei deinem 2. Beispiel manipulierst Du nicht die Instanz sondern die Klasse. mach ne 2. Instanz, und über diese kannst Du dann auch auf new_sitevars zugreiffen, diese hat aber wieder den gleichen Inhalt für alle Instanzen.
Dies liesse sich über Metaclassen unterbinden, sollte aber bei vernünftigen Programmierern nicht nötig sein ;)

Im übrigen reichts eine Basisklasse zu kennen, Abgeleitete Klassen können dann genau wie die Basisklasse verwendet werden, siehe z.B. boole.


Gruß

Dookie
Gast

hi dookie!

interessant und verwirrend ist, dass dasselbe bsp im old style, tatsächlich nur die klasse ändert und die objekte nicht drauf reagieren. ich dachte zuerst, dass das mit ganz was anderem zu tun hat, dass die instanzen der new style klassen reagieren.

war ein irrtum. in momentaner verwirrung muss ich zu dem schlusss kommen :D :D :
wer objekte und klasse dynamsich ändern will und will dass die objekte drauf reagieren muss __slots__ verwenden.

Code: Alles auswählen

#!/usr/local/bin/python


class Test(object):
    
    __slots__=['site_vars']
    base_vars={'a' : '1',
               'b' : '2',
               'c' : '3',
               'd' : ''}
    def __init__(self, **kw):
            self.site_vars=self.base_vars.copy()
            self.site_vars.update(kw)
    def __str__(self):
            site=str(self.site_vars.values())
            return site

Code: Alles auswählen

>>> t=Test()
>>> u=Test()
>>> print t
['1', '3', '2', '']
>>> print u
['1', '3', '2', '']
>>> Test.site_vars={'a':'geandert','b':'auch geaendert'}
>>> print t
['geandert', 'auch geaendert']
>>> print u
['geandert', 'auch geaendert']
>>> v=Test()

Traceback (most recent call last):
  File "<pyshell#7>", line 1, in -toplevel-
    v=Test()
  File "/home/rolgal/polen/python/new_style_class_a.py", line 12, in __init__
    self.site_vars=self.base_vars.copy()
AttributeError: 'Test' object attribute 'site_vars' is read-only
>>> Test.new_site_vars={'a':'und wieder','b':'so ein spass'}
>>> print t
['geandert', 'auch geaendert']
>>> print u
['geandert', 'auch geaendert']
>>> print u.new_site_vars
{'a': 'und wieder', 'b': 'so ein spass'}
allerdings ist auch interessant, dass er keine neue instanz anlegen lässt.

ganz anders verhalten sich die instanzen hier:

Code: Alles auswählen

#!/usr/local/bin/python

class Test:

    base_vars={'a':'1',
               'b':'2',
               'c':'3',
               'd':''}

    def __init__(self, **kw):
            self.site_vars=self.base_vars.copy()
            self.site_vars.update(kw)
    def __str__(self):
            site=str(self.site_vars.values())
            return site

Code: Alles auswählen

>>> t=Test()
>>> u=Test()
>>> print t
['1', '3', '2', '']
>>> print u
['1', '3', '2', '']
>>> Test.site_vars={'a':'geandert','b':'auch geaendert'}
>>> print t
['1', '3', '2', '']
>>> print u
['1', '3', '2', '']
siehst was ich meine? im ersten bsp. haben sich die objekte angepasst, im zweiten nicht.

:D

Code: Alles auswählen

__slots__
fördert für unvernünfige programmierer die dynamische änderung

ganz offensichtlich hat

Code: Alles auswählen

__slots__
mit dem einfluss auf die kopie von

Code: Alles auswählen

base_vars
zu tun, denn:

Code: Alles auswählen

#!/usr/local/bin/python

class Test:

    base_vars={'a':'1',
               'b':'2',
               'c':'3',
               'd':''}

    def __init__(self, **kw):
            self.base_vars.update(kw)
    def __str__(self):
            site=str(self.base_vars.values())
            return site
führt dann doch zu dem ergebnis wie bei der new_style klasse:

Code: Alles auswählen

>>> t=Test()
>>> u=Test()
>>> print t
['1', '3', '2', '']
>>> print u
['1', '3', '2', '']
>>> Test.base_vars={'a':'geandert','b':'auch geandert'}
>>> print t
['geandert', 'auch geandert']
>>> print u
['geandert', 'auch geandert']
>>> 
lol, dann ist ja

Code: Alles auswählen

__slots__
für nichts gut.
sorry, der stoff ist so trocken ich muss das mit etwas humor angehen, es ist ja schliesslich auch sonntag.

mfg

rolgal


mfg

rolgal
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hi,

der Zugriff ist bei newstyle Klassen ein anderer als der auf oldstyle Klassen. Auch ein Grund Klassen und Intanzen nicht von aussen auf diese Weise zu ändern, da es gänzlich andere Ergebnisse liefert.
Du änderst keine Objekte sondern die Klasse mit Deinem Beispiel!
Klassen sind bei New-Style auch Objekte.


Gruß

Dookie
Gast

???

aber die objekte sind auch geändert, oder nicht?

ausser bei dem bsp. der old_style klasse mit dem selben konstruktor, wie ihn die new_style klasse hat.

mfg

rolgal
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

!!!

nö eben nicht, es sind die Klassenattribute die du änderst, nicht die Objekte.
Über die Objekte kannst Du natürlich dann auf die geänderten Klassenattribute zugreifen.
Klassen sind die Beschreibung um Objekte(Instanzen) zu erzeugen. Objekte sind mit Hilfe der Beschreibung in der Klasse erzeugte Konkrete "Objekte" eben.
Objekte von Oldstyle Klassen oder Newstyle Klassen ohne __slots__ haben ein Attribut __dict__ in dem die Attribute und Methoden in einem Dictionary festgehalten sind. Über __dict__ erfolgt dann der Zugriff auf die Attribute und Methoden.
Objekte von Newstyle Klassen mit __slots__ haben kein Attribut __dict__ und der Zugriff auf Attribute und Methoden erfolgt anders, wie braucht hier nicht zu Interessieren ist aber in der Pythondocumentation zu Newstyle Klassen beschrieben, kann sich aber bei Python 3.x oder 4.x wieder total ändern, darum brauchts nicht zu interessieren.


Gruß

Dookie
Gast

hi

ist

Code: Alles auswählen

a=A()
ein verweis auf ein objekt, ja oder nein?

ja. wenn ich nun die klassenattribute so ändere, dass beim aufruf von

Code: Alles auswählen

print a
diese neue klassenattribute zur verfügung stehen, dann verweist wohl a auf ein objekt mit den geänderten attributen. also ist das objekt geändert.

mfg

rolgal
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

hi auch,

Code: Alles auswählen

a = A()
A.cattr = "Hallo"
print "A sagt:", A.cattr
print "a sagt auch:", a.cattr
b = A()
print "b sagt, na was wohl:", b.cattr
so wird ein neues Klassenattribut erzeugt und Klassenattribute sind sowohl über die Klasse als auch über die Instanzen zugreifbar und in den genannten Fällen wird auf ein und das selbe Attribut zugegriffen das auch für alle Instanzen und die Klasse den gleichen Wert hat.


Gruß

Dookie
Gast

hi dookie!

äh, ich weiss eigentlich nicht was du mir jetzt klar machen wolltest.

was du mir zeigst ist vollkommen klar. ich sagte ja: ich ändere die klassen!!! erreiche aber daurch auch die angelegten instanzen und je nach bsp hat es sich ausgewirkt oder nicht!

eben auch im falle von

Code: Alles auswählen

__slots__
hat es sich auf die instanzen, den attributen der instanzen ausgewirkt, wenn dir diese formulierung lieber ist.

logisch, dass ich

Code: Alles auswählen

__slots__
als schutzmechanismus in der von dir erklärten form in frage stelle.

pythons oop konzept ist offen. warum konnte noch immer nicht geklärt werden.

mfg

rolgal
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

ich wollte dir klar machen, daß du klassenattribute und attribute von instanzen, auch wenn beim lesenden Zugriff scheinbar kein Unterschied ist, dieses doch 2 völlig verschiedene Sachen sind.
Du erreichst keine Instanzen indem du Klassenattribute änderst, sondern über die Instanzen hast du zugriff auf Klassenattribute!!!
Solange dir dieses nicht klar ist, ist eine weitere Diskussion sinnlos.


Gruß

Dookie
Gast

also gut!

klasse A. attribut - wert
instanz a greit auf diesen wert zu.

klasse A. attribut - geänderter wert.
instanz a greift auf diesen wert zu.

der ursprgl. wert ist nicht mehr erreichbar.

somit repräsentiert der verweis a ein objekt mit einem attribut dessen wert geändert wurde.

was stimmt daran nicht?

ob du es von dieser seite oder jener seite angehst: fakt ist, beim aufruf a.attribut, kommt nach der änderung der geänderte wert.

mfg

rolgal
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

was daran nicht stimmt ist, das A.irgendwas kein attribut von a sondern ein attribut von A ist, a.irgendwas wird zu A.irgendwas umgeleitet. Funktioniert also wie ein Alias. Und es ist nicht egal von welcher Seite du es siehst, wenn Du in einen Lautsprecher reinsingst, kommt beim Microfon ja auch kein Ton heraus.


Gruß

Dookie
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Hi. Du sagst es: Verweise, Referenzen. Es sind nun mal Klassenatrribute und die sind für alle Instanzen immer gleich. Das durch Eingriffe darin rumgepfuscht werden kann ist klar und deswegen auch, dass man darauf aufpassen sollte (nun merkst du ja selber warum). Es herrscht Identität zwischen Klassenattributen.

Deswegen hat das auch gar nix mit __slots__ zu tun, da das nur dafür da ist, das keine neuen Attribute hinzugefügt werden können, es schützt nicht vor Änderung bestehender Attribute (wie du in der Docu lesen kannst).

Warum du nun also schreibenden Zugriff auf die Klassenattribute hast, musst du die Pythonentwickler fragen. Es ist jedenfalls in der Sprachphilosophie verankert, dass man offener zugreifen darf als anderswo. Das war auch der Grund, wesegen Dookie und ich stark gegen einen offenen Zugriff aus "Lust und Laune" argumentiert haben, wenn es nicht anders geht. Hier könntest du aber auch eine große Ausnahme machen, wenn du a) den Quellcode kennst und b) gerade diese Identität als nützliches Mittel erwünscht ist. Man kann damit technische Kunstgriffe machen, sollte es aber als Ausnahme behandeln und möglichst andere Wege gehen.

Milan
Gast

du hast schon recht, dass ich das genauer formulieren muss.

das ergebnis ist im gegensatz zu deinem vergleich mit dem lautsprecher doch das gleiche.

a.attribut gibt mir das zurück was ich in der klasse definiert habe.

warum also __slots__ wenn, abgesehen davon ob es sinn macht oder nicht, ich das was a.attribut zurückgibt so leicht beeinflussen kann.

ist das so unklar was ich meine :D ?

wenn ich etwas implementiere um es zu schützen, dann muss ich es schon richtig dicht machen.

mir kommt __slots__ (ist ja für was anderes auch noch gut) so vor, als würde ich meine gitarre in einen koffer sperren und auf den koffer draufschreiben wo der schlüssel ist.

oder so ähnlich.

mfg

rolgal
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hi rolgal,

__slots__ gibt die Anzahl und die Namen der Seiten einer Gitarre an. Jede Gitarre dieses Typs hat genau die Anzahl Seiten und diese haben die Namen die in __slots__ definiert sind. Du kannst nicht wahllos Seiten hinzugeben. Kannst aber auch mal eine Seite erneuern, also ihr einen neuen Wert zuweisen.
In der Gitarre klebt ein Zettelchen, mit dem Hersteller und dessen Webseite oder Emailadresse. Wenn nun der Hersteller in seiner Firma im Lager Holz aus Neuguinea bekommt, so bekommt der Herstellers ein neues Attribut, über den Zettel in der Gitarre könntest Du nun auf dieses neue Attribut des herstellers zugreifen, aber die Gitarre selber ändert sich dadurch nicht.


Gruß

Dookie
Gast

hi dookie!

wenn man den ganzen tag sich mit einer sache beschäftigt, so wie ich heute mit new style klassen, dann gerät manchmal was durcheinander. ich werde versuchen das zu ordnen:

Code: Alles auswählen

#!/usr/local/bin/python


class Test(object):
    
    __slots__=['site_vars']
    base_vars={'a' : '1',
               'b' : '2',
               'c' : '3',
               'd' : ''}
    
    def __init__(self, **kw):
            self.site_vars=self.base_vars.copy()
            self.site_vars.update(kw)
            
    def __str__(self):
            site=str(self.site_vars.values())
            return site
kennen wir nun schon:

jetzt schau das mal: instanzierung, namensraum von a:

Code: Alles auswählen

>>> a=Test()
>>> print a
['1', '3', '2', '']
>>> dir(a)
['__class__', '__delattr__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__slots__', '__str__', 'base_vars', 'site_vars']
>>> 
nun ändere ich die klasse:

Code: Alles auswählen

>>> Test.new_site_vars={'new_a':'new_1','new_b':'new_2'}
und nun noch einmal der namensraum von a:

Code: Alles auswählen


>>> dir(a)
['__class__', '__delattr__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__slots__', '__str__', 'base_vars', 'new_site_vars', 'site_vars']
a verweist nun auf ein objekt, das über new_site_vars verfügt:

Code: Alles auswählen

>>> print a.new_site_vars
{'new_b': 'new_2', 'new_a': 'new_1'}
>>> 
fazit:

Code: Alles auswählen

__slots__
sollte verhindern, dass die instanz a auf ein objekt verweist, dass mehr als die attribute

Code: Alles auswählen

site_vars
verfügt. durch die änderung der klasse ist dies aber nicht mehr der fall.

und zudem meinte ich: wenn

Code: Alles auswählen

__slots__
auch diese funktion hätte, dann sollte auch dafür gesorgt sein, dass man es nicht einfach so manipulieren kann.

ich hoffe, ich habe es jetzt von allen versuchen am besten formuliert. :D

mfg

rolgal
Gast

hi milan

grundsätzliches zu

Code: Alles auswählen

__slots__
, siehe bitte antwort für dookie.

Warum du nun also schreibenden Zugriff auf die Klassenattribute hast, musst du die Pythonentwickler fragen.
ja, um die frage und deren beantwortung ging es mir ganz ursprünglich. wollten sie neue aspekte für oop ermöglichen oder ist es wirklich ein unfug der ihnen unterlaufen ist?. ganz ursprgl. wollte ich die diese möglichkeiten und ihre nützlichkeite im dialog ausloten.
Hier könntest du aber auch eine große Ausnahme machen, wenn du a) den Quellcode kennst
davon bin ich auch immer ausgegangen. denn angefangen hat ja alles mit einem modul von mir, dass versch. webseiten zur verfügung stellt, also diese dynamisch erstellt.
b) gerade diese Identität als nützliches Mittel erwünscht ist.
hm, ich will jetzt nicht losreden, weil ich nicht ganz sicher bin, ob wir dasselbe meinen. kannst du bitte konkretisieren?
Man kann damit technische Kunstgriffe machen
den verdacht habe ich eben auch, irgendwie.
sollte es aber als Ausnahme behandeln und möglichst andere Wege gehen.
darüber bin ich mir noch nicht im klaren.
1. python war ursprgl. als skriptsprache für kleiner projekte gedacht (ich suche schon die ganze zeit nach dem zitat...) , d. h. man kann davon ausgehen, dass man in etwa dachte: 1 entwickler - kennt seinen quellcode, restrektive massnahmen sind nicht notwendig.
2. python ist auffallend offen konzipiert. ich kann mir in einem gespräch mit den entwicklern folgendes nur schwer vorstellen:
"nun ja, das gibts jetzt schon seit jahren, wir haben uns nichts dabei gedacht und irgendwie haben wir uns dann gedacht, wenn wir schon scheisse bauen, sollten wir konsequent bleiben und keine echten private attribute erlauben (wie echt sie sind ist mir auch noch nicht klar, da liest man viel verwirrendes) und dann haben wir mit

Code: Alles auswählen

__slots__
noch eins draufgesetzt, das zwar die anzahl und die namen der attribute einer instanz schützen sollte, aber wenn du die klasse umänderst, dann kannst den unfug weiter betreiben"

naja, das war jetzt nur der versuch die problematik, die ich mit dem thema habe etwas humoristisch darzustellen.

es ist abslolut nicht als angriff auf die art und weise wie du oder dookie o.a. oop versteht und umsetzt zu verstehen.
ich schreibe das deshalb, weil geschriebenes leichter missverstanden werden kann, als gesprochenes.

mfg
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hi Rolgal,

mir ist vorhin in der Badewanne ein Beispiel speziell für Dich eingefallen:

Wenn Du Gitarre spielst, variierst Du die Töne ja auch nicht durch drehen an den Wirbeln sondern indem Du die Seiten auf das Griffbrett drückst.
Hat der Gitarrenbauer nun Misst gebaut weil er es erlaubt an den Wribeln die Tonhöhe der Seiten zu ändern?
Eigentlich nicht, sonst könntest Du die Gitarre ja nicht stimmen.


Gruß

Dookie
Gast

hi dookie!

das beispiel ist geil!!!!

dennoch, in der modernen musik musst du mit allem gefasst sein. und wie du selbst sagtest: ich muss die gitarre ja stimmen. d.h. diese möglichkeit muss vorhanden sein.

die veränderung von klassen und objekten von aussen auch :?: :D

ok, für heute verzieh ich mich....

gute nacht, schönen wochenbeginn.

hast du dir eigentlich die obigen bsp. angeguckt? das mit

Code: Alles auswählen

dir(a) 
finde ich echt interessant.

mfg

rolgal
Antworten