Code: Alles auswählen
class Musterklasse:
version = '0.2.3 buggy'
#Anwendercode:
print(Musterklasse.version)
#aber folgendes soll dem Anwender streng verboten sein:
Kl.version = '1.2.3 prima'
print(Musterklasse.version)
Code: Alles auswählen
class Musterklasse:
version = '0.2.3 buggy'
#Anwendercode:
print(Musterklasse.version)
#aber folgendes soll dem Anwender streng verboten sein:
Kl.version = '1.2.3 prima'
print(Musterklasse.version)
Code: Alles auswählen
class Musterklasse(object):
VERSION = '0.2.3 buggy'
Code: Alles auswählen
class MetaThing(type):
@property
def version(self):
return '0.2.3 buggy'
class Thing(metaclass=MetaThing):
pass
print(Thing.version)
Schön wäre es, aber nein: der Anwender bin ich selber .Sirius3 hat geschrieben:Es ist nicht Deine Aufgabe, den Anwender zu erziehen.
Das ist ok und für mich das kleinere Problem. Wenn ich schon eine gesamte Klasse umschreibe, dann wird eine einzelne Zeile mehr wohl keine Katastrofe sein.Sirius3 hat geschrieben: Jetzt muß ich die version-Property der Metaklasse überschreiben, wenn ich die Version ändern will...
Also mit ein paar schmutzigen Reflection-Tricks sollte man grundsätzlich an jedes beliebige private Objekt kommen. Ich selbst habe erst vor wenigen Monaten erfolgreich in dieser Hinsicht herumexperimentiert. Kann natürlich sein, dass die Patch-Orgie der letzten Wochen irgendwas daran verändert hat. Müsste man halt mal ausprobieren.Sirius3 hat geschrieben:zu streng verboten fällt mir immer Java ein. Es mag ja für den Puristen eine Befriedigung sein, bestimmte Methoden protected oder sogar private zu deklarieren und für OpenSource-Packete hält sich der Aufwand auch noch einigermaßen in Grenzen sich seine Freiheiten zu schaffen, wenn man aber dann ganze Klassen nachprogrammieren muß, weil sie von außen nicht zugänglich sind und man auf anderem Weg die Bugs nicht geradebügeln kann, dann ist das nicht nur nervig, sondern kostet auch einen ganzen Nachmittag, an dem man mit seinem Projekt eigentlich viel weiter kommen wollte.
Code: Alles auswählen
class BaseType(object):
def __init__(self):
self._version = None
@property
def version(self):
return self._version
@version.setter
def version(self, value):
if self._version is not None:
msg = 'cannot overwrite existing version value'
raise AttributeError(msg)
self._version = value
Code: Alles auswählen
from collections import namedtuple
class metaKl(type):
@property
def PersonTpl(self):
return namedtuple( "PersonTpl", "vorname name geburtstag" )
class Kl(metaclass=metaKl):
@property
def PersonTpl(self): return Kl.PersonTpl.__doc__ #greift nicht
#Anwendercode
try: Kl.PersonTpl = namedtuple( "PersonTpl", "name steuernummer" )
except: print("Umdefinition von \"Kl.PersonTpl\" wurde ignoriert")
print()
kl = Kl()
kl.person = Kl.PersonTpl('Geo','Mondmann',19690720)
#kl.person = kl.PersonTpl('Geo','Mondmann',19690720) #Fehler, aber kann damit leben
print(Kl.PersonTpl) #UNBRAUCHBAR, sollte Inhalt von Kl.PersonTpl.__doc__ ausgeben
print(kl.person) #gut
print(kl.person.name) #ausgezeichnet
Danke, das ermutigt michsnafu hat geschrieben:eine Vererbungsstruktur, in der man nicht versehentlich das Versionsattribut der Superklasse überschreiben soll. In diesem Fall fände ich ein Property sogar ganz in Ordnung.
Code: Alles auswählen
from collections import namedtuple
class Aufgabenstellung(object):
PersonTpl = namedtuple('PersonTpl', 'vorname name geburtstag')
def __init__(self):
self.person = None
def main():
aufgabenstellung = Aufgabenstellung()
aufgabenstellung.person = Aufgabenstellung.PersonTpl(
'Geo', 'Mondmann', 19690720
)
print Aufgabenstellung.PersonTpl.__doc__
print aufgabenstellung.person
print aufgabenstellung.person.name
Ich habe Grundkenntnisse (keine Programmiererfahrung) in Java, und das von dir empfohlene Buch habe ich vor einigen Jahren überflogen. Ich habe es dann beiseitegelassen, weil viele Konzepte, auf welche das Buches großen Wert legt, in Python nicht realisierbar sind, insbesondere Kapselung und Interfaces . Ja ich würde ohne Übertreibung sagen, dass meine von euch so empfundene "Python-feindliche" Einstellung ihren Ursprung in *genau diesem Buch* hat, vorher war ich da (als ehemaliger Fortran-Programmierer) viel lockerer. Deshalb wundert es mich echt, dass dieses Buch von einem Python-Anhänger empfohlen wird.pillmuncher hat geschrieben:Ich empfehle dazu dieses Buch. Es setzt zwar Grundkenntnisse in Java voraus., aber die sind an einem Wochenende leicht soweit erlernbar, dass man damit das Buch durcharbeiten kann.
Code: Alles auswählen
class FooBarObservable:
def __init__(self):
self._observers = set()
self._foo = 0
self._bar = 0
def register(self, observer):
self._observers.add(observer)
def remove(self, observer):
self._observers.remove(observer)
@property
def foo(self):
return self._foo
@foo.setter
def foo(self, value):
self._foo = value
for each in self._observers:
each.foo_changed(self)
@property
def bar(self):
return self._bar
@bar.setter
def bar(self, value):
self._bar = value
for each in self._observers:
each.bar_changed(self)
class FooBarObserver:
def __init__(self, identity):
self._identity = identity
def foo_changed(self, observable):
print('Observer {}: observed foo value changed to {}'.format(
self._identity, observable.foo))
def bar_changed(self, observable):
print('Observer {}: observed bar value changed to {}'.format(
self._identity, observable.bar))
server = FooBarObservable()
client1 = FooBarObserver(1)
client2 = FooBarObserver(2)
client3 = FooBarObserver(3)
server.register(client1)
server.register(client2)
server.register(client3)
server.foo = 3
server.remove(client2)
server.bar = 4
Code: Alles auswählen
Observer 1: observed foo value changed to 3
Observer 2: observed foo value changed to 3
Observer 3: observed foo value changed to 3
Observer 1: observed bar value changed to 4
Observer 3: observed bar value changed to 4
Das weiß ich nicht nur, sondern habe es in allen meinen Programmen auch so gemacht, seitdem ich Python verwende, was jetzt einige Jahre her ist. Alles Gegenteilige sind Gedankenkonstrukte (aka "Hirngespinste") von einigen Mitgliedern in diesem Forum. Wenn ich Schwierigkeiten habe (und die habe ich öfters), meine Python-Programme zum Laufen zu bringen oder zu verwalten, hat das *absolut gar nichts* damit zu tun.pillmuncher hat geschrieben: Wenn man signalisieren möchte, dass ein Attribut privat ist und von außen nicht geändert werden sollte, versieht man dessen Namen - per Konvention - mit einem führenden Unterstrich.