How to add property to a class dynamically?

前端 未结 24 1913
梦毁少年i
梦毁少年i 2020-11-22 12:44

The goal is to create a mock class which behaves like a db resultset.

So for example, if a database query returns, using a dict expression, {\'ab\':100, \'cd\'

相关标签:
24条回答
  • 2020-11-22 13:09

    To answer the main thrust of your question, you want a read-only attribute from a dict as an immutable datasource:

    The goal is to create a mock class which behaves like a db resultset.

    So for example, if a database query returns, using a dict expression, {'ab':100, 'cd':200}, then I would to see

    >>> dummy.ab
    100
    

    I'll demonstrate how to use a namedtuple from the collections module to accomplish just this:

    import collections
    
    data = {'ab':100, 'cd':200}
    
    def maketuple(d):
        '''given a dict, return a namedtuple'''
        Tup = collections.namedtuple('TupName', d.keys()) # iterkeys in Python2
        return Tup(**d)
    
    dummy = maketuple(data)
    dummy.ab
    

    returns 100

    0 讨论(0)
  • 2020-11-22 13:10

    How to add property to a python class dynamically?

    Say you have an object that you want to add a property to. Typically, I want to use properties when I need to begin managing access to an attribute in code that has downstream usage, so that I can maintain a consistent API. Now I will typically add them to the source code where the object is defined, but let's assume you don't have that access, or you need to truly dynamically choose your functions programmatically.

    Create a class

    Using an example based on the documentation for property, let's create a class of object with a "hidden" attribute and create an instance of it:

    class C(object):
        '''basic class'''
        _x = None
    
    o = C()
    

    In Python, we expect there to be one obvious way of doing things. However, in this case, I'm going to show two ways: with decorator notation, and without. First, without decorator notation. This may be more useful for the dynamic assignment of getters, setters, or deleters.

    Dynamic (a.k.a. Monkey Patching)

    Let's create some for our class:

    def getx(self):
        return self._x
    
    def setx(self, value):
        self._x = value
    
    def delx(self):
        del self._x
    

    And now we assign these to the property. Note that we could choose our functions programmatically here, answering the dynamic question:

    C.x = property(getx, setx, delx, "I'm the 'x' property.")
    

    And usage:

    >>> o.x = 'foo'
    >>> o.x
    'foo'
    >>> del o.x
    >>> print(o.x)
    None
    >>> help(C.x)
    Help on property:
    
        I'm the 'x' property.
    

    Decorators

    We could do the same as we did above with decorator notation, but in this case, we must name the methods all the same name (and I'd recommend keeping it the same as the attribute), so programmatic assignment is not so trivial as it is using the above method:

    @property
    def x(self):
        '''I'm the 'x' property.'''
        return self._x
    
    @x.setter
    def x(self, value):
        self._x = value
    
    @x.deleter
    def x(self):
        del self._x
    

    And assign the property object with its provisioned setters and deleters to the class:

    C.x = x
    

    And usage:

    >>> help(C.x)
    Help on property:
    
        I'm the 'x' property.
    
    >>> o.x
    >>> o.x = 'foo'
    >>> o.x
    'foo'
    >>> del o.x
    >>> print(o.x)
    None
    
    0 讨论(0)
  • 2020-11-22 13:10

    Just another example how to achieve desired effect

    class Foo(object):
    
        _bar = None
    
        @property
        def bar(self):
            return self._bar
    
        @bar.setter
        def bar(self, value):
            self._bar = value
    
        def __init__(self, dyn_property_name):
            setattr(Foo, dyn_property_name, Foo.bar)
    

    So now we can do stuff like:

    >>> foo = Foo('baz')
    >>> foo.baz = 5
    >>> foo.bar
    5
    >>> foo.baz
    5
    
    0 讨论(0)
  • 2020-11-22 13:11

    Something that works for me is this:

    class C:
        def __init__(self):
            self._x=None
    
        def g(self):
            return self._x
    
        def s(self, x):
            self._x = x
    
        def d(self):
            del self._x
    
        def s2(self,x):
            self._x=x+x
    
        x=property(g,s,d)
    
    
    c = C()
    c.x="a"
    print(c.x)
    
    C.x=property(C.g, C.s2)
    C.x=C.x.deleter(C.d)
    c2 = C()
    c2.x="a"
    print(c2.x)
    

    Output

    a
    aa
    
    0 讨论(0)
  • 2020-11-22 13:12

    Although many answers are given, I couldn't find one I am happy with. I figured out my own solution which makes property work for the dynamic case. The source to answer the original question:

    #!/usr/local/bin/python3
    
    INITS = { 'ab': 100, 'cd': 200 }
    
    class DP(dict):
      def __init__(self):
        super().__init__()
        for k,v in INITS.items():
            self[k] = v 
    
    def _dict_set(dp, key, value):
      dp[key] = value
    
    for item in INITS.keys():
      setattr(
        DP,
        item,
        lambda key: property(
          lambda self: self[key], lambda self, value: _dict_set(self, key, value)
        )(item)
      )
    
    a = DP()
    print(a)  # {'ab': 100, 'cd': 200}
    a.ab = 'ab100'
    a.cd = False
    print(a.ab, a.cd) # ab100 False
    
    0 讨论(0)
  • 2020-11-22 13:12

    A lot of the supplied answers require so many lines per property, ie / and / or - what I'd consider an ugly or tedious implementation because of repetitiveness required for multiple properties, etc. I prefer keeping boiling things down / simplifying them until they can't be simplified anymore or until it doesn't serve much purpose to do so.

    In short: in completed works, if I repeat 2 lines of code, I typically convert it into a single line helper function, and so on... I simplify math or odd arguments such as ( start_x, start_y, end_x, end_y ) to ( x, y, w, h ) ie x, y, x + w, y + h ( sometimes requiring min / max or if w / h are negative and the implementation doesn't like it, I'll subtract from x / y and abs w / h. etc.. ).

    Overriding the internal getters / setters is an ok way to go, but the problem is you need to do that for every class, or parent the class to that base... This doesn't work for me as I'd prefer to be free to choose the children / parents for inheritance, child nodes, etc.

    I have created a solution which answers the question without using a Dict data-type to supply the data as I find that to be tedious to enter the data, etc...

    My solution requires you to add 2 extra lines above your class to create a base class for the class you want to add the properties to, then 1 line per and you have the option to add callbacks to control the data, inform you when data changes, restrict the data which can be set based on value and / or data-type, and much more.

    You also have the option to use _object.x, _object.x = value, _object.GetX( ), _object.SetX( value ) and they are handled equivalently.

    Additionally, the values are the only non-static data which are assigned to the class instance, but the actual property is assigned to the class meaning the things you don't want to repeat, don't need to be repeated... You can assign a default value so the getter doesn't need it each time, although there is an option to override the default default value, and there is another option so the getter returns the raw stored value by overriding default returns ( note: this method means the raw value is only assigned when a value is assigned, otherwise it is None - when the value is Reset, then it assigns None, etc.. )

    There are many helper functions too - the first property which gets added adds 2 or so helpers to the class for referencing the instance values... They are ResetAccessors( _key, .. ) varargs repeated ( all can be repeated using the first named args ) and SetAccessors( _key, _value ) with the option of more being added to the main class to aide in efficiency - the ones planned are: a way to group accessors together, so if you tend to reset a few at a time, every time, you can assign them to a group and reset the group instead of repeating the named keys each time, and more.

    The instance / raw stored value is stored at class., the __class. references the Accessor Class which holds static vars / values / functions for the property. _class. is the property itself which is called when accessed via the instance class during setting / getting, etc.

    The Accessor _class.__ points to the class, but because it is internal it needs to be assigned in the class which is why I opted to use __Name = AccessorFunc( ... ) to assign it, a single line per property with many optional arguments to use ( using keyed varargs because they're easier and more efficient to identify and maintain )...

    I also create a lot of functions, as mentioned, some of which use accessor function information so it doesn't need to be called ( as it is a bit inconvenient at the moment - right now you need to use _class..FunctionName( _class_instance, args ) - I got around using the stack / trace to grab the instance reference to grab the value by adding the functions which either run this bit marathon, or by adding the accessors to the object and using self ( named this to point out they're for the instance and to retain access to self, the AccessorFunc class reference, and other information from within the function definitions ).

    It isn't quite done, but it is a fantastic foot-hold. Note: If you do not use __Name = AccessorFunc( ... ) to create the properties, you won't have access to the __ key even though I define it within the init function. If you do, then there are no issues.

    Also: Note that Name and Key are different... Name is 'formal', used in Function Name Creation, and the key is for data storage and access. ie _class.x where lowercase x is key, the name would be uppercase X so that GetX( ) is the function instead of Getx( ) which looks a little odd. this allows self.x to work and look appropriate, but also allow GetX( ) and look appropriate.

    I have an example class set up with key / name identical, and different to show. a lot of helper functions created in order to output the data ( Note: Not all of this is complete ) so you can see what is going on.

    The current list of functions using key: x, name: X outputs as:

    This is by no means a comprehensive list - there are a few which haven't made it on this at the time of posting...

    _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
    

    Some of the data being output is:

    This is for a brand new class created using the Demo class without any data assigned other than the name ( so it can be output ) which is _foo, the variable name I used...

    _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)
    

    And this is after assigning all of _foo properties ( except the name ) the following values in the same order: '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)                                                                                                                                                                                                   |
    

    Note that because of restricted data-types or value restrictions, some data wasn't assigned - this is by design. The setter prohibits bad data-types or values from being assigned, even from being assigned as a default value ( unless you override the default value protection behavior )

    The code hasn't been posted here because I didn't have room after the examples and explanations... Also because it will change.

    Please Note: at the time of this posting, the file is messy - this will change. But, if you run it in Sublime Text and compile it, or run it from Python, it will compile and spit out a ton of information - the AccessorDB portion isn't done ( which will be used to update the Print Getters and GetKeyOutput helper functions along with being changed to an Instance function, probably put into a single function and renamed - look for it.. )

    Next: Not everything is required for it to run - a lot of the commented stuff at the bottom is for more information used for debugging - it may not be there when you download it. If it is, you should be able to uncomment and recompile to get more information.

    I am looking for a work-around to needing MyClassBase: pass, MyClass( MyClassBase ): ... - if you know of a solution - post it.

    The only thing necessary in the class are the __ lines - the str is for debugging as is the init - they can be removed from the Demo Class but you will need to comment out or remove some of the lines below ( _foo / 2 / 3 )..

    The String, Dict, and Util classes at the top are a part of my Python library - they are not complete. I copied over a few things I needed from the library, and I created a few new ones. The full code will link to the complete library and will include it along with providing updated calls and removing the code ( actually, the only code left will be the Demo Class and the print statements - the AccessorFunc system will be moved to the library )...

    Part of file:

    ##
    ## 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 = { } )
    

    This beauty makes it incredibly easy to create new classes with dynamically added properties with AccessorFuncs / callbacks / data-type / value enforcement, etc.

    For now, the link is at ( This link should reflect changes to the document. ): https://www.dropbox.com/s/6gzi44i7dh58v61/dynamic_properties_accessorfuncs_and_more.py?dl=0

    Also: If you don't use Sublime Text, I recommend it over Notepad++, Atom, Visual Code, and others because of proper threading implementations making it much, much faster to use... I am also working on an IDE-like code mapping system for it - take a look at: https://bitbucket.org/Acecool/acecoolcodemappingsystem/src/master/ ( Add Repo in Package Manager first, then Install Plugin - when version 1.0.0 is ready, I'll add it to the main plugin list... )

    I hope this solution helps... and, as always:

    Just because it works, doesn't make it right - Josh 'Acecool' Moser

    0 讨论(0)
提交回复
热议问题