synth.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. """
  2. Copyright (c) Contributors to the Open 3D Engine Project.
  3. For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. SPDX-License-Identifier: Apache-2.0 OR MIT
  5. """
  6. # -------------------------------------------------------------------------
  7. # -------------------------------------------------------------------------
  8. # synth.py
  9. # Convenience module for a standardized attr interface for classes/objects.
  10. # version: 0.1
  11. # date: 11/14/2013
  12. # author: jGalloway
  13. # -------------------------------------------------------------------------
  14. __author__ = 'HogJonny'
  15. # -------------------------------------------------------------------------
  16. """
  17. This module contains the function
  18. .synthesize(inst, name, value, readonly=False)
  19. It is useful in object oriented class attributes, providing a stardard
  20. interface for creating properties of classes.
  21. Can be called within an objects Class, or an instance of an object can be
  22. passed into the function to have the properties added. The property will
  23. be added and set/get/del attr interface will be created.
  24. """
  25. # --------------------------------------------------------------------------
  26. def synthesize(inst, name, value, readonly=False):
  27. """
  28. Convenience method to create getters, setters and a property for the
  29. instance. Should the instance already have the getters or setters
  30. defined this won't add them and the property will reference the already
  31. defined getters and setters Should be called from within __init__.
  32. Creates [name], _[name], get[Name], set[Name], del[Name], and on inst.
  33. :param inst: An instance of the class to add the methods to.
  34. :param name: Base name to build function names and storage variable.
  35. :param value: Initial state of the created variable.
  36. """
  37. cls = type(inst)
  38. storageName = '_{0}'.format(name)
  39. getterName = 'get{0}{1}'.format(name[0].capitalize(), name[1:])
  40. setterName = 'set{0}{1}'.format(name[0].capitalize(), name[1:])
  41. deleterName = 'del{0}{1}'.format(name[0].capitalize(), name[1:])
  42. setattr(inst, storageName, value)
  43. # We always define the getter
  44. def buildCustomGetter(self):
  45. return getattr(self, storageName)
  46. # Add the Getter
  47. if not hasattr(inst, getterName):
  48. setattr(cls, getterName, buildCustomGetter)
  49. # Handle Read Only
  50. if readonly:
  51. if not hasattr(inst, name):
  52. setattr(cls, name,
  53. property(fget=getattr(cls, getterName, None) or buildCustomGetter,
  54. fdel=getattr(cls, getterName, None)))
  55. else:
  56. # We only define the setter if we arn't read only
  57. def buildCustomSetter(self, state):
  58. setattr(self, storageName, state)
  59. if not hasattr(inst, setterName):
  60. setattr(cls, setterName, buildCustomSetter)
  61. member = None
  62. if hasattr(cls, name):
  63. # we need to try to update the property fget, fset, fdel
  64. # incase the class has defined its own custom functions
  65. member = getattr(cls, name)
  66. if not isinstance(member, property):
  67. raise ValueError('Member "{0}" for class "{1}" exists and is not a property.'
  68. ''.format(name, cls.__name__))
  69. # If the class has the property or not we still try to set it
  70. setattr(cls, name,
  71. property(fget=getattr(member, 'fget', None)
  72. or getattr(cls, getterName, None)
  73. or buildCustomGetter,
  74. fset=getattr(member, 'fset', None)
  75. or getattr(cls, setterName, None)
  76. or buildCustomSetter,
  77. fdel=getattr(member, 'fdel', None)
  78. or getattr(cls, getterName, None)))
  79. return getattr(inst, name)
  80. # --------------------------------------------------------------------------
  81. ###########################################################################
  82. # Main Code Block, will run the tool
  83. # -------------------------------------------------------------------------
  84. if __name__ == '__main__':
  85. """Self Testing"""
  86. from test_foo import Foo
  87. # create an object from Foo Class
  88. myFoo = Foo()
  89. pass