제공된 답변을 많이 얻으려면 속성 당 너무 많은 줄이 필요합니다. 즉, 여러 속성에 필요한 반복성으로 인해 추악하거나 지루한 구현이라고 생각합니다. 더 이상 단순화 할 수 없거나 그렇게 할 목적이 없을 때까지
간단히 말하면, 완성 된 작품에서 2 줄의 코드를 반복하면 일반적으로 한 줄 도우미 함수로 변환하는 등의 식으로 시작합니다. (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)를 사용하는 옵션도 있으며 동등하게 처리됩니다.
또한 값은 클래스 인스턴스에 할당 된 비 정적 데이터 만 유일하지만 실제 속성은 클래스에 할당되어 반복하고 싶지 않으며 반복 할 필요가없는 것을 의미합니다. 기본 기본값을 재정의하는 옵션이 있지만 getter가 매번 필요하지 않도록 기본값을 할당 할 수 있으며 다른 옵션이 있으므로 getter가 기본 반환 값을 재정 의하여 원시 저장된 값을 반환합니다 (참고 :이 방법 값이 할당 될 때만 원시 값이 할당되고 그렇지 않으면 None입니다. 값이 Reset 인 경우 None 등이 할당됩니다.)
많은 도우미 함수도 있습니다-추가되는 첫 번째 속성은 인스턴스 값을 참조하기 위해 클래스에 도우미를 2 개 정도 추가합니다 ... 이들은 ResetAccessors (_key, ..) varargs입니다 (모두 첫 번째 명명 된 인수를 사용하여 반복 할 수 있음) ) 및 SetAccessors (_key, _value)는 효율성을 높이기 위해 메인 클래스에 추가되는 옵션이 있습니다. 계획된 방법은 다음과 같습니다. 접근자를 그룹화하는 방법입니다. 따라서 매번 몇 번 재설정하는 경향이 있습니다. , 매번 이름 지정된 키를 반복하는 대신 그룹에 할당하고 그룹을 재설정 할 수 있습니다.
인스턴스 / 원시 저장 값은 클래스에 저장됩니다 ., 클래스. 속성에 대한 정적 변수 / 값 / 함수를 보유하는 접근 자 클래스를 참조합니다. _수업. 설정 / 가져 오기 등의 동안 인스턴스 클래스를 통해 액세스 할 때 호출되는 속성 자체입니다.
접근 자 _class .__은 클래스를 가리 키지 만 내부적으로 클래스에 할당해야하기 때문에 __Name = AccessorFunc (...)를 사용하여 할당합니다. 사용할 인수 (키워드 된 varargs를 사용하면 더 쉽고 효율적으로 식별하고 유지 관리 할 수 있음) ...
또한 언급 한 것처럼 많은 함수를 작성합니다. 일부 함수 는 접근 자 함수 정보 를 사용 하므로 호출 할 필요가 없습니다 (지금은 약간 불편하므로 _class를 사용해야합니다. .FunctionName (_class_instance , args)-스택 / 추적을 사용 하여이 비트 마라톤을 실행하는 함수를 추가하거나 객체에 접근자를 추가하고 self를 사용하여 값을 가져 오기 위해 인스턴스 참조를 가져옵니다. '인스턴스를위한 것이며 함수 정의 내에서 self, AccessorFunc 클래스 참조 및 기타 정보에 대한 액세스 권한을 유지해야합니다.
아직 완료되지는 않았지만 환상적인 발판입니다. 참고 : 속성을 만드는 데 __Name = AccessorFunc (...)를 사용하지 않으면 init 함수 내에서 정의하더라도 __ 키에 액세스 할 수 없습니다. 그렇게하면 아무런 문제가 없습니다.
또한 : 이름과 키가 다르다는 점에 유의하십시오. 이름은 '형식적'이며 기능 이름 작성에 사용되며 키는 데이터 저장 및 액세스를위한 것입니다. 즉, 소문자 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)
그리고 이것은 'string', 1.0, True, 9, 10, False와 같은 순서로 모든 _foo 속성 (name 제외)에 다음 값을 할당 한 후입니다.
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) |
제한된 데이터 유형 또는 값 제한으로 인해 일부 데이터가 할당되지 않았습니다. 이것은 의도적으로 설계된 것입니다. 세터는 잘못된 데이터 유형 또는 값이 기본값으로 지정되지 않은 경우 (기본값 보호 동작을 무시하지 않는 한) 금지합니다.
예제와 설명 뒤에 여유가 없었기 때문에 코드가 게시되지 않았습니다 ... 또한 변경 될 것입니다.
참고 :이 게시물을 게시 할 때 파일이 지저분합니다-변경됩니다. 그러나 Sublime Text에서 실행하고 컴파일하거나 Python에서 실행하면 많은 정보를 컴파일하고 뱉어냅니다 .AccessorDB 부분은 수행되지 않습니다 (인쇄 Getter 및 GetKeyOutput 도우미를 업데이트하는 데 사용됨) 함수를 인스턴스 함수로 변경하고 단일 함수에 넣고 이름을 바꿉니다.)
다음 : 실행에 필요한 모든 것은 아닙니다. 하단에 주석이 달린 많은 부분은 디버깅에 사용되는 자세한 정보를위한 것입니다. 다운로드 할 때 없을 수도 있습니다. 그렇다면 주석 처리를 해제하고 다시 컴파일하여 자세한 정보를 얻을 수 있어야합니다.
MyClassBase : pass, MyClass (MyClassBase) : ...-해결 방법을 알고 있다면 게시하십시오.
클래스에 필요한 유일한 것은 __ 줄입니다. str 은 초기화 와 마찬가지로 디버깅 입니다. 데모 클래스에서 제거 할 수 있지만 아래 줄을 주석 처리하거나 제거해야합니다 (_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를 사용하지 않으면 적절한 스레딩 구현으로 인해 메모장 ++, Atom, Visual Code 및 기타를 사용하는 것이 좋습니다. 사용하기 훨씬 훨씬 빠릅니다. 나는 IDE와 같은 코드로 작업하고 있습니다. 그것을 위해 매핑 시스템 - 한 번 봐 걸릴 : https://bitbucket.org/Acecool/acecoolcodemappingsystem/src/master/은 - 버전 1.0.0가 준비되면, 내가 추가 할 것 (다음 설치를 먼저 패키지 관리자에서 플러그인을 리포 추가 메인 플러그인 목록으로 ...)
이 솔루션이 도움이 되길 바랍니다.
Josh 'Acecool'Moser
:
및__init__
reference가 필요합니다self.fn_readyonly
.