提供された回答の多くは、プロパティごとに非常に多くの行を必要とします。つまり、/および/または-複数のプロパティに必要な反復性などのために、醜い、または面倒な実装と見なすものです。簡略化することはできません、またはそれを行うための多くの目的を果たさなくなるまでは。
簡単に言うと、完成した作品で2行のコードを繰り返す場合、通常は1行のヘルパー関数に変換します。以下のように、数式や(start_x、start_y、end_x、end_y)などの奇数引数を簡略化します。 (x、y、w、h)すなわちx、y、x + w、y + h(min / maxが必要な場合、またはw / hが負で実装がそれを好まない場合は、x /から減算しますyおよびabs w / hなど)。
内部ゲッター/セッターをオーバーライドするのは良い方法ですが、問題は、すべてのクラスに対してそれを行うか、クラスをそのベースにペアレント化する必要があることです...私はそうしたくないので、私にはうまくいきません継承のための子/親、子ノードなどを自由に選択できます
私は、Dictデータ型を使用せずに質問に答えるソリューションを作成しました。データを入力するのが面倒であるなどの理由でデータを提供するためです...
私のソリューションでは、プロパティを追加するクラスの基本クラスを作成するために、クラスの上に2行を追加する必要があります。その後、1行ずつ追加し、コールバックを追加してデータを制御し、データが変更されたときに通知するオプションがあります。 、値やデータタイプなどに基づいて設定できるデータを制限します。
_object.x、_object.x = value、_object.GetX()、_ object.SetX(value)を使用するオプションもあり、それらは同等に処理されます。
さらに、値はクラスインスタンスに割り当てられる唯一の非静的データですが、実際のプロパティはクラスに割り当てられます。つまり、繰り返したくない、繰り返す必要がないことを意味します...デフォルト値を割り当てることができるので、デフォルトのデフォルト値をオーバーライドするオプションがありますが、ゲッターは毎回デフォルト値を必要としません。また、別のオプションがあるので、ゲッターはデフォルトのリターンをオーバーライドすることにより、生の保存値を返します(注:このメソッド生の値は、値が割り当てられた場合にのみ割り当てられることを意味します。それ以外の場合は、Noneです。値がリセットされると、Noneなどが割り当てられます。)
多くのヘルパー関数もあります-追加される最初のプロパティは、インスタンス値を参照するためにクラスに2つほどのヘルパーを追加します...それらは、ResetAccessors(_key、..)varargsの繰り返しです(すべて、最初の名前付き引数を使用して繰り返すことができます) )とSetAccessors(_key、_value)オプションを追加して、効率を上げるためにメインクラスに追加する-計画されているものは、アクセサをグループ化する方法です。そのため、一度にいくつかをリセットする傾向がある場合、名前付きキーを毎回繰り返す代わりに、それらをグループに割り当ててグループをリセットできます。
インスタンス/保存された生の値はクラスに保存されます。、 クラス。プロパティの静的変数/値/関数を保持するアクセサクラスを参照します。_クラス。設定/取得などの際にインスタンスクラスを介してアクセスされたときに呼び出されるプロパティ自体です。
アクセサー_class .__はクラスを指しますが、それは内部であるため、クラスに割り当てる必要があります。そのため、私は__Name = AccessorFunc(...)を使用してそれを割り当てることを選択しました。使用する引数(キー付き変数を使用すると、識別および保守が簡単かつ効率的になります)...
また、前述のように多くの関数を作成しますが、その一部はアクセサ関数情報を使用するため、呼び出す必要はありません(現時点では少し不便なので、_classを使用する必要があります。.FunctionName(_class_instance 、args)-このビットマラソンを実行する関数を追加するか、オブジェクトにアクセサーを追加してself(これを指すためにthisという名前を付ける)を追加することにより、スタック/トレースを使用してインスタンス参照を取得し、値を取得しました'インスタンス用であり、関数定義内からの自分、AccessorFuncクラス参照、およびその他の情報へのアクセスを保持します)。
それはまだ完全ではありませんが、素晴らしい足掛かりです。注:__Name = AccessorFunc(...)を使用してプロパティを作成しない場合、__キーにアクセスできなくなります。その場合、問題はありません。
また、名前とキーは異なることに注意してください...名前は「正式」で、関数名の作成で使用され、キーはデータの保存とアクセス用です。つまり、小文字のxがキーである_class.xの場合、名前は大文字のXになるため、GetX()が少し奇妙に見えるGetx()の代わりに関数になります。これにより、self.xが機能して適切に見えるようになるだけでなく、GetX()も適切に見えるようになります。
キー/名前が同じで、表示するクラスが異なるサンプルクラスを設定しています。データを出力するために作成された多くのヘルパー関数(注:これがすべて完了しているわけではありません)なので、何が起こっているのかを確認できます。
key:x、name:Xを使用する関数の現在のリストは、次のように出力されます。
これは決して包括的なリストではありません-投稿時にまだリストに載っていないものもいくつかあります...
_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
出力されるデータの一部は次のとおりです。
これは、Demoクラスを使用して作成されたまったく新しいクラス用であり、名前以外のデータが割り当てられていないため(出力できるため)、使用した変数名_fooです...
_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)
そして、これはすべての_fooプロパティ(名前を除く)に同じ順序で次の値を割り当てた後です: '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) |
制限されたデータ型または値の制限のため、一部のデータは割り当てられなかったことに注意してください-これは仕様によるものです。setterは、デフォルト値として割り当てられている場合でも、不適切なデータ型または値の割り当てを禁止します(デフォルト値の保護動作をオーバーライドしない限り)。
例と説明の後にスペースがなかったため、コードはここに掲載されていません...また、コードが変更されるためです。
注:この投稿の時点では、ファイルは乱雑です-これは変更されます。しかし、Sublime Textで実行してコンパイルするか、Pythonから実行すると、大量の情報がコンパイルされて吐き出されます-AccessorDB部分は実行されません(Print GetterおよびGetKeyOutputヘルパーの更新に使用されます)関数は、インスタンス関数に変更されるとともに、おそらく単一の関数に入れられて名前が変更されます-それを探してください。
次:実行にすべてが必要なわけではありません-下部にあるコメント付きのものの多くは、デバッグに使用される詳細情報用です-ダウンロードしたときに表示されない場合があります。その場合は、コメントを外して再コンパイルし、詳細情報を取得できます。
MyClassBase:pass、MyClass(MyClassBase):...が必要な回避策を探しています-解決策を知っている場合-投稿してください。
クラスで必要なのは__行のみです。strはinitと同様にデバッグ用です。これらはデモクラスから削除できますが、以下の行の一部をコメント化または削除する必要があります(_foo / 2/3 )。
上部のString、Dict、およびUtilクラスは、私のPythonライブラリの一部です-完全ではありません。ライブラリから必要なものをいくつかコピーして、新しいものをいくつか作成しました。完全なコードは完全なライブラリにリンクし、更新された呼び出しの提供とコードの削除とともにそれを含めます(実際には、残っているコードは、デモクラスと印刷ステートメントだけです-AccessorFuncシステムはライブラリに移動されます)。 ..
ファイルの一部:
##
## 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 = { } )
この美しさにより、AccessorFuncs /コールバック/データタイプ/値の強制などで動的に追加されるプロパティを持つ新しいクラスを非常に簡単に作成できます。
現時点では、リンクは(このリンクはドキュメントへの変更を反映している必要があります):https : //www.dropbox.com/s/6gzi44i7dh58v61/dynamic_properties_accessorfuncs_and_more.py?dl=0
また、Sublime Textを使用しない場合は、適切なスレッド化の実装により、はるかに高速に使用できるため、Notepad ++、Atom、Visual Codeなどよりもお勧めします... IDEのようなコードにも取り組んでいますそのためのマッピングシステム-見てください:https : //bitbucket.org/Acecool/acecoolcodemappingsystem/src/master/(最初にパッケージマネージャーにリポジトリを追加してからプラグインをインストール-バージョン1.0.0の準備ができたら、追加しますそれをメインのプラグインリストに...)
この解決策がお役に立てば幸いです...そして、いつものように:
機能するからといって正しく機能しない-Josh 'Acecool' Moser
:
と__init__
参照が必要self.fn_readyonly
です。