Viele der bereitgestellten Antworten erfordern so viele Zeilen pro Eigenschaft, dh / und / oder - was ich als hässliche oder langwierige Implementierung betrachten würde, da für mehrere Eigenschaften Wiederholungen erforderlich sind usw. Ich ziehe es vor, die Dinge so lange zu reduzieren / zu vereinfachen, bis sie vorliegen kann nicht mehr vereinfacht werden oder bis es nicht mehr viel Sinn hat, dies zu tun.
Kurz gesagt: Wenn ich in abgeschlossenen Arbeiten zwei Codezeilen wiederhole, konvertiere ich sie normalerweise in eine einzeilige Hilfsfunktion usw. Ich vereinfache mathematische oder ungerade Argumente wie (start_x, start_y, end_x, end_y) in (x, y, w, h) dh x, y, x + w, y + h (manchmal ist min / max erforderlich oder wenn w / h negativ ist und die Implementierung es nicht mag, werde ich von x / subtrahieren y und abs w / h. etc ..).
Das Überschreiben der internen Getter / Setter ist ein guter Weg, aber das Problem ist, dass Sie dies für jede Klasse tun müssen oder die Klasse dieser Basis zuordnen müssen ... Dies funktioniert bei mir nicht so, wie ich es vorziehen würde frei zu wählen die Kinder / Eltern für Vererbung, Kinderknoten, etc.
Ich habe eine Lösung erstellt, die die Frage beantwortet, ohne einen Dict-Datentyp zur Bereitstellung der Daten zu verwenden, da ich die Eingabe der Daten usw. als mühsam empfinde.
Meine Lösung erfordert, dass Sie 2 zusätzliche Zeilen über Ihrer Klasse hinzufügen, um eine Basisklasse für die Klasse zu erstellen, zu der Sie die Eigenschaften hinzufügen möchten. Dann 1 Zeile pro Klasse. Sie haben die Möglichkeit, Rückrufe hinzuzufügen, um die Daten zu steuern und Sie zu informieren, wenn sich Daten ändern , beschränken Sie die Daten, die basierend auf Wert und / oder Datentyp festgelegt werden können, und vieles mehr.
Sie haben auch die Möglichkeit, _object.x, _object.x = value, _object.GetX (), _object.SetX (value) zu verwenden, und diese werden gleich behandelt.
Darüber hinaus sind die Werte die einzigen nicht statischen Daten, die der Klasseninstanz zugewiesen sind, aber die tatsächliche Eigenschaft wird der Klasse zugewiesen, dh die Dinge, die Sie nicht wiederholen möchten, müssen nicht wiederholt werden ... Sie kann einen Standardwert zuweisen, damit der Getter ihn nicht jedes Mal benötigt, obwohl es eine Option zum Überschreiben des Standardstandardwerts gibt, und es gibt eine andere Option, damit der Getter den gespeicherten Rohwert durch Überschreiben der Standardrückgaben zurückgibt (Hinweis: Diese Methode bedeutet, dass der Rohwert nur zugewiesen wird, wenn ein Wert zugewiesen wird, andernfalls ist er None - wenn der Wert Reset ist, weist er None usw. zu.)
Es gibt auch viele Hilfsfunktionen - die erste Eigenschaft, die hinzugefügt wird, fügt der Klasse ungefähr 2 Helfer hinzu, um auf die Instanzwerte zu verweisen ... Es handelt sich um ResetAccessors (_key, ..) -Varargs, die wiederholt werden (alle können mit den zuerst genannten Argumenten wiederholt werden ) und SetAccessors (_key, _value) mit der Option, der Hauptklasse mehr hinzuzufügen, um die Effizienz zu verbessern. Geplant sind: eine Möglichkeit, Accessoren zu gruppieren. Wenn Sie also dazu neigen, jedes Mal einige zurückzusetzen Sie können sie einer Gruppe zuweisen und die Gruppe zurücksetzen, anstatt die genannten Schlüssel jedes Mal zu wiederholen.
Der gespeicherte Instanz- / Rohwert wird in der Klasse gespeichert . , die Klasse. verweist auf die Accessor-Klasse, die statische Variablen / Werte / Funktionen für die Eigenschaft enthält. _Klasse. ist die Eigenschaft selbst, die beim Zugriff über die Instanzklasse beim Setzen / Abrufen usw. aufgerufen wird.
Die Accessor _class .__ zeigt auf die Klasse, aber da sie intern ist, muss sie in der Klasse zugewiesen werden, weshalb ich mich für die Verwendung von __Name = AccessorFunc (...) entschieden habe, eine einzelne Zeile pro Eigenschaft mit vielen optionalen zu verwendende Argumente (unter Verwendung von Keyed Varargs, da sie einfacher und effizienter zu identifizieren und zu warten sind) ...
Wie bereits erwähnt, erstelle ich auch viele Funktionen, von denen einige Accessor-Funktionsinformationen verwenden, sodass sie nicht aufgerufen werden müssen (da dies im Moment etwas unpraktisch ist - im Moment müssen Sie _class verwenden. .FunctionName (_class_instance) verwenden , args) - Ich bin herumgekommen, indem ich den Stack / Trace verwendet habe, um die Instanzreferenz abzurufen, um den Wert zu ermitteln, indem ich die Funktionen hinzugefügt habe, die entweder diesen Bitmarathon ausführen, oder indem ich die Accessoren zum Objekt hinzugefügt und self verwendet habe (benannte dies, um darauf hinzuweisen) sind für die Instanz und um den Zugriff auf sich selbst, die AccessorFunc-Klassenreferenz und andere Informationen aus den Funktionsdefinitionen zu behalten).
Es ist noch nicht ganz fertig, aber es ist ein fantastischer Halt. Hinweis: Wenn Sie zum Erstellen der Eigenschaften nicht __Name = AccessorFunc (...) verwenden, haben Sie keinen Zugriff auf die Taste __, obwohl ich sie in der Init-Funktion definiert habe. Wenn Sie dies tun, gibt es keine Probleme.
Außerdem: Beachten Sie, dass Name und Schlüssel unterschiedlich sind ... Der Name ist 'formal' und wird bei der Erstellung von Funktionsnamen verwendet. Der Schlüssel dient zur Datenspeicherung und zum Zugriff. dh _class.x wobei x in Kleinbuchstaben der Schlüssel ist, wäre der Name Großbuchstabe X, so dass GetX () die Funktion anstelle von Getx () ist, was etwas seltsam aussieht. Dadurch kann self.x funktionieren und angemessen aussehen, aber auch GetX () und angemessen aussehen.
Ich habe eine Beispielklasse eingerichtet, deren Schlüssel / Name identisch und unterschiedlich ist. Viele Hilfsfunktionen wurden erstellt, um die Daten auszugeben (Hinweis: Nicht alles ist vollständig), damit Sie sehen können, was los ist.
Die aktuelle Liste der Funktionen mit key: x, name: X gibt Folgendes aus:
Dies ist keineswegs eine umfassende Liste - es gibt einige, die es zum Zeitpunkt der Veröffentlichung noch nicht geschafft haben ...
_instance.SetAccessors( _key, _value [ , _key, _value ] .. ) Instance Class Helper Function: Allows assigning many keys / values on a single line - useful for initial setup, or to minimize lines. In short: Calls this.Set<Name>( _value ) for each _key / _value pairing.
_instance.ResetAccessors( _key [ , _key ] .. ) Instance Class Helper Function: Allows resetting many key stored values to None on a single line. In short: Calls this.Reset<Name>() for each name provided.
Note: Functions below may list self.Get / Set / Name( _args ) - self is meant as the class instance reference in the cases below - coded as this in AccessorFuncBase Class.
this.GetX( _default_override = None, _ignore_defaults = False ) GET: Returns IF ISSET: STORED_VALUE .. IF IGNORE_DEFAULTS: None .. IF PROVIDED: DEFAULT_OVERRIDE ELSE: DEFAULT_VALUE 100
this.GetXRaw( ) RAW: Returns STORED_VALUE 100
this.IsXSet( ) ISSET: Returns ( STORED_VALUE != None ) True
this.GetXToString( ) GETSTR: Returns str( GET ) 100
this.GetXLen( _default_override = None, _ignore_defaults = False ) LEN: Returns len( GET ) 3
this.GetXLenToString( _default_override = None, _ignore_defaults = False ) LENSTR: Returns str( len( GET ) ) 3
this.GetXDefaultValue( ) DEFAULT: Returns DEFAULT_VALUE 1111
this.GetXAccessor( ) ACCESSOR: Returns ACCESSOR_REF ( self.__<key> ) [ AccessorFuncBase ] Key: x : Class ID: 2231452344344 : self ID: 2231448283848 Default: 1111 Allowed Types: {"<class 'int'>": "<class 'type'>", "<class 'float'>": "<class 'type'>"} Allowed Values: None
this.GetXAllowedTypes( ) ALLOWED_TYPES: Returns Allowed Data-Types {"<class 'int'>": "<class 'type'>", "<class 'float'>": "<class 'type'>"}
this.GetXAllowedValues( ) ALLOWED_VALUES: Returns Allowed Values None
this.GetXHelpers( ) HELPERS: Returns Helper Functions String List - ie what you're reading now... THESE ROWS OF TEXT
this.GetXKeyOutput( ) Returns information about this Name / Key ROWS OF TEXT
this.GetXGetterOutput( ) Returns information about this Name / Key ROWS OF TEXT
this.SetX( _value ) SET: STORED_VALUE Setter - ie Redirect to __<Key>.Set N / A
this.ResetX( ) RESET: Resets STORED_VALUE to None N / A
this.HasXGetterPrefix( ) Returns Whether or Not this key has a Getter Prefix... True
this.GetXGetterPrefix( ) Returns Getter Prefix... Get
this.GetXName( ) Returns Accessor Name - Typically Formal / Title-Case X
this.GetXKey( ) Returns Accessor Property Key - Typically Lower-Case x
this.GetXAccessorKey( ) Returns Accessor Key - This is to access internal functions, and static data... __x
this.GetXDataKey( ) Returns Accessor Data-Storage Key - This is the location where the class instance value is stored.. _x
Einige der ausgegebenen Daten sind:
Dies ist für eine brandneue Klasse, die mit der Demo-Klasse erstellt wurde, ohne dass andere Daten als der Name zugewiesen wurden (damit sie ausgegeben werden können). Dies ist _foo, der Variablenname, den ich verwendet habe ...
_foo --- MyClass: ---- id( this.__class__ ): 2231452349064 :::: id( this ): 2231448475016
Key Getter Value | Raw Key Raw / Stored Value | Get Default Value Default Value | Get Allowed Types Allowed Types | Get Allowed Values Allowed Values |
Name: _foo | _Name: _foo | __Name.DefaultValue( ): AccessorFuncDemoClass | __Name.GetAllowedTypes( ) <class 'str'> | __Name.GetAllowedValues( ) Saved Value Restrictions Levied by Data-Type |
x: 1111 | _x: None | __x.DefaultValue( ): 1111 | __x.GetAllowedTypes( ) (<class 'int'>, <class 'float'>) | __x.GetAllowedValues( ) Saved Value Restrictions Levied by Data-Type |
y: 2222 | _y: None | __y.DefaultValue( ): 2222 | __y.GetAllowedTypes( ) (<class 'int'>, <class 'float'>) | __y.GetAllowedValues( ) Saved Value Restrictions Levied by Data-Type |
z: 3333 | _z: None | __z.DefaultValue( ): 3333 | __z.GetAllowedTypes( ) (<class 'int'>, <class 'float'>) | __z.GetAllowedValues( ) Saved Value Restrictions Levied by Data-Type |
Blah: <class 'int'> | _Blah: None | __Blah.DefaultValue( ): <class 'int'> | __Blah.GetAllowedTypes( ) <class 'str'> | __Blah.GetAllowedValues( ) Saved Value Restrictions Levied by Data-Type |
Width: 1 | _Width: None | __Width.DefaultValue( ): 1 | __Width.GetAllowedTypes( ) (<class 'int'>, <class 'bool'>) | __Width.GetAllowedValues( ) Saved Value Restrictions Levied by Data-Type |
Height: 0 | _Height: None | __Height.DefaultValue( ): 0 | __Height.GetAllowedTypes( ) <class 'int'> | __Height.GetAllowedValues( ) (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) |
Depth: 2 | _Depth: None | __Depth.DefaultValue( ): 2 | __Depth.GetAllowedTypes( ) Saved Value Restricted to Authorized Values ONLY | __Depth.GetAllowedValues( ) (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) |
this.IsNameSet( ): True this.GetName( ): _foo this.GetNameRaw( ): _foo this.GetNameDefaultValue( ): AccessorFuncDemoClass this.GetNameLen( ): 4 this.HasNameGetterPrefix( ): <class 'str'> this.GetNameGetterPrefix( ): None
this.IsXSet( ): False this.GetX( ): 1111 this.GetXRaw( ): None this.GetXDefaultValue( ): 1111 this.GetXLen( ): 4 this.HasXGetterPrefix( ): (<class 'int'>, <class 'float'>) this.GetXGetterPrefix( ): None
this.IsYSet( ): False this.GetY( ): 2222 this.GetYRaw( ): None this.GetYDefaultValue( ): 2222 this.GetYLen( ): 4 this.HasYGetterPrefix( ): (<class 'int'>, <class 'float'>) this.GetYGetterPrefix( ): None
this.IsZSet( ): False this.GetZ( ): 3333 this.GetZRaw( ): None this.GetZDefaultValue( ): 3333 this.GetZLen( ): 4 this.HasZGetterPrefix( ): (<class 'int'>, <class 'float'>) this.GetZGetterPrefix( ): None
this.IsBlahSet( ): False this.GetBlah( ): <class 'int'> this.GetBlahRaw( ): None this.GetBlahDefaultValue( ): <class 'int'> this.GetBlahLen( ): 13 this.HasBlahGetterPrefix( ): <class 'str'> this.GetBlahGetterPrefix( ): None
this.IsWidthSet( ): False this.GetWidth( ): 1 this.GetWidthRaw( ): None this.GetWidthDefaultValue( ): 1 this.GetWidthLen( ): 1 this.HasWidthGetterPrefix( ): (<class 'int'>, <class 'bool'>) this.GetWidthGetterPrefix( ): None
this.IsDepthSet( ): False this.GetDepth( ): 2 this.GetDepthRaw( ): None this.GetDepthDefaultValue( ): 2 this.GetDepthLen( ): 1 this.HasDepthGetterPrefix( ): None this.GetDepthGetterPrefix( ): (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
this.IsHeightSet( ): False this.GetHeight( ): 0 this.GetHeightRaw( ): None this.GetHeightDefaultValue( ): 0 this.GetHeightLen( ): 1 this.HasHeightGetterPrefix( ): <class 'int'> this.GetHeightGetterPrefix( ): (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
Und dies ist, nachdem alle _foo-Eigenschaften (außer dem Namen) die folgenden Werte in derselben Reihenfolge zugewiesen haben: 'string', 1.0, True, 9, 10, False
this.IsNameSet( ): True this.GetName( ): _foo this.GetNameRaw( ): _foo this.GetNameDefaultValue( ): AccessorFuncDemoClass this.GetNameLen( ): 4 this.HasNameGetterPrefix( ): <class 'str'> this.GetNameGetterPrefix( ): None
this.IsXSet( ): True this.GetX( ): 10 this.GetXRaw( ): 10 this.GetXDefaultValue( ): 1111 this.GetXLen( ): 2 this.HasXGetterPrefix( ): (<class 'int'>, <class 'float'>) this.GetXGetterPrefix( ): None
this.IsYSet( ): True this.GetY( ): 10 this.GetYRaw( ): 10 this.GetYDefaultValue( ): 2222 this.GetYLen( ): 2 this.HasYGetterPrefix( ): (<class 'int'>, <class 'float'>) this.GetYGetterPrefix( ): None
this.IsZSet( ): True this.GetZ( ): 10 this.GetZRaw( ): 10 this.GetZDefaultValue( ): 3333 this.GetZLen( ): 2 this.HasZGetterPrefix( ): (<class 'int'>, <class 'float'>) this.GetZGetterPrefix( ): None
this.IsBlahSet( ): True this.GetBlah( ): string Blah this.GetBlahRaw( ): string Blah this.GetBlahDefaultValue( ): <class 'int'> this.GetBlahLen( ): 11 this.HasBlahGetterPrefix( ): <class 'str'> this.GetBlahGetterPrefix( ): None
this.IsWidthSet( ): True this.GetWidth( ): False this.GetWidthRaw( ): False this.GetWidthDefaultValue( ): 1 this.GetWidthLen( ): 5 this.HasWidthGetterPrefix( ): (<class 'int'>, <class 'bool'>) this.GetWidthGetterPrefix( ): None
this.IsDepthSet( ): True this.GetDepth( ): 9 this.GetDepthRaw( ): 9 this.GetDepthDefaultValue( ): 2 this.GetDepthLen( ): 1 this.HasDepthGetterPrefix( ): None this.GetDepthGetterPrefix( ): (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
this.IsHeightSet( ): True this.GetHeight( ): 9 this.GetHeightRaw( ): 9 this.GetHeightDefaultValue( ): 0 this.GetHeightLen( ): 1 this.HasHeightGetterPrefix( ): <class 'int'> this.GetHeightGetterPrefix( ): (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
_foo --- MyClass: ---- id( this.__class__ ): 2231452349064 :::: id( this ): 2231448475016
Key Getter Value | Raw Key Raw / Stored Value | Get Default Value Default Value | Get Allowed Types Allowed Types | Get Allowed Values Allowed Values |
Name: _foo | _Name: _foo | __Name.DefaultValue( ): AccessorFuncDemoClass | __Name.GetAllowedTypes( ) <class 'str'> | __Name.GetAllowedValues( ) Saved Value Restrictions Levied by Data-Type |
x: 10 | _x: 10 | __x.DefaultValue( ): 1111 | __x.GetAllowedTypes( ) (<class 'int'>, <class 'float'>) | __x.GetAllowedValues( ) Saved Value Restrictions Levied by Data-Type |
y: 10 | _y: 10 | __y.DefaultValue( ): 2222 | __y.GetAllowedTypes( ) (<class 'int'>, <class 'float'>) | __y.GetAllowedValues( ) Saved Value Restrictions Levied by Data-Type |
z: 10 | _z: 10 | __z.DefaultValue( ): 3333 | __z.GetAllowedTypes( ) (<class 'int'>, <class 'float'>) | __z.GetAllowedValues( ) Saved Value Restrictions Levied by Data-Type |
Blah: string Blah | _Blah: string Blah | __Blah.DefaultValue( ): <class 'int'> | __Blah.GetAllowedTypes( ) <class 'str'> | __Blah.GetAllowedValues( ) Saved Value Restrictions Levied by Data-Type |
Width: False | _Width: False | __Width.DefaultValue( ): 1 | __Width.GetAllowedTypes( ) (<class 'int'>, <class 'bool'>) | __Width.GetAllowedValues( ) Saved Value Restrictions Levied by Data-Type |
Height: 9 | _Height: 9 | __Height.DefaultValue( ): 0 | __Height.GetAllowedTypes( ) <class 'int'> | __Height.GetAllowedValues( ) (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) |
Depth: 9 | _Depth: 9 | __Depth.DefaultValue( ): 2 | __Depth.GetAllowedTypes( ) Saved Value Restricted to Authorized Values ONLY | __Depth.GetAllowedValues( ) (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) |
Beachten Sie, dass aufgrund eingeschränkter Datentypen oder Werteinschränkungen einige Daten nicht zugewiesen wurden - dies ist beabsichtigt. Der Setter verhindert, dass fehlerhafte Datentypen oder Werte zugewiesen werden, auch wenn sie nicht als Standardwert zugewiesen werden (es sei denn, Sie überschreiben das Standardwertschutzverhalten).
Der Code wurde hier nicht veröffentlicht, weil ich nach den Beispielen und Erklärungen keinen Platz hatte ... Auch weil er sich ändern wird.
Bitte beachten Sie: Zum Zeitpunkt dieses Beitrags ist die Datei unordentlich - dies wird sich ändern. Wenn Sie es jedoch in Sublime Text ausführen und kompilieren oder in Python ausführen, werden eine Menge Informationen kompiliert und ausgespuckt - der AccessorDB-Teil wird nicht ausgeführt (der zum Aktualisieren des Print Getters- und GetKeyOutput-Hilfsprogramms verwendet wird Funktionen zusammen mit der Änderung in eine Instanzfunktion, wahrscheinlich in eine einzelne Funktion eingefügt und umbenannt - suchen Sie danach ..)
Weiter: Es ist nicht alles erforderlich, damit es ausgeführt werden kann. Viele der kommentierten Elemente unten enthalten weitere Informationen zum Debuggen. Möglicherweise ist es beim Herunterladen nicht vorhanden. Wenn dies der Fall ist, sollten Sie in der Lage sein, Kommentare abzugeben und neu zu kompilieren, um weitere Informationen zu erhalten.
Ich suche nach einer Lösung, um MyClassBase zu benötigen: pass, MyClass (MyClassBase): ... - wenn Sie eine Lösung kennen - posten Sie sie.
Das einzige, was in der Klasse benötigt wird, sind die __-Zeilen - der str dient zum Debuggen, ebenso wie der init - sie können aus der Demo-Klasse entfernt werden, aber Sie müssen einige der folgenden Zeilen auskommentieren oder entfernen (_foo / 2/3 ) ..
Die Klassen String, Dict und Util oben sind Teil meiner Python-Bibliothek - sie sind nicht vollständig. Ich habe ein paar Dinge, die ich brauchte, aus der Bibliothek kopiert und ein paar neue erstellt. Der vollständige Code wird mit der gesamten Bibliothek verknüpft und enthält diese zusammen mit der Bereitstellung aktualisierter Aufrufe und dem Entfernen des Codes (der einzige verbleibende Code ist die Demo-Klasse und die Druckanweisungen - das AccessorFunc-System wird in die Bibliothek verschoben). ..
Teil der Datei:
##
## MyClass Test AccessorFunc Implementation for Dynamic 1-line Parameters
##
class AccessorFuncDemoClassBase( ):
pass
class AccessorFuncDemoClass( AccessorFuncDemoClassBase ):
__Name = AccessorFuncBase( parent = AccessorFuncDemoClassBase, name = 'Name', default = 'AccessorFuncDemoClass', allowed_types = ( TYPE_STRING ), allowed_values = VALUE_ANY, documentation = 'Name Docs', getter_prefix = 'Get', key = 'Name', allow_erroneous_default = False, options = { } )
__x = AccessorFuncBase( parent = AccessorFuncDemoClassBase, name = 'X', default = 1111, allowed_types = ( TYPE_INTEGER, TYPE_FLOAT ), allowed_values = VALUE_ANY, documentation = 'X Docs', getter_prefix = 'Get', key = 'x', allow_erroneous_default = False, options = { } )
__Height = AccessorFuncBase( parent = AccessorFuncDemoClassBase, name = 'Height', default = 0, allowed_types = TYPE_INTEGER, allowed_values = VALUE_SINGLE_DIGITS, documentation = 'Height Docs', getter_prefix = 'Get', key = 'Height', allow_erroneous_default = False, options = { } )
Diese Schönheit macht es unglaublich einfach, neue Klassen mit dynamisch hinzugefügten Eigenschaften mit AccessorFuncs / Rückrufen / Datentyp / Wertdurchsetzung usw. zu erstellen.
Derzeit befindet sich der Link unter (Dieser Link sollte Änderungen am Dokument widerspiegeln.): Https://www.dropbox.com/s/6gzi44i7dh58v61/dynamic_properties_accessorfuncs_and_more.py?dl=0
Außerdem: Wenn Sie Sublime Text nicht verwenden, empfehle ich ihn gegenüber Notepad ++, Atom, Visual Code und anderen, da die Verwendung von Threading-Implementierungen die Verwendung erheblich beschleunigt. Ich arbeite auch an einem IDE-ähnlichen Code Mapping-System dafür - werfen Sie einen Blick auf: https://bitbucket.org/Acecool/acecoolcodemappingsystem/src/master/ (Repo zuerst im Paket-Manager hinzufügen, dann Plugin installieren - wenn Version 1.0.0 fertig ist, werde ich hinzufügen es zur Haupt-Plugin-Liste ...)
Ich hoffe diese Lösung hilft ... und wie immer:
Nur weil es funktioniert, macht es nicht richtig - Josh 'Acecool' Moser
:
und__init__
Verweiseself.fn_readyonly
.