Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ########################################################################################################################
- # File: dict2object.py
- # Author: Dan Huckson, https://github.com/unodan
- # Date: 2019-01-25
- ########################################################################################################################
- class _BaseObject:
- def __init__(self, path, **config):
- self._id = None
- self._uri = None
- self._type = None
- self._parent = None
- self._config = config
- for key, value in config.items():
- if isinstance(value, dict):
- if key in dir(self):
- attributes = []
- for attribute in dir(self):
- if attribute.startswith('_'):
- continue
- attributes.append(attribute)
- attributes = ', '.join(attributes)
- _class = f'<{self.__class__.__name__}>'
- raise KeyError(f'The key "{key}" is a {_class} reserved attribute. Reserved Keywords: {attributes}')
- uri = f'{path}/{key}'
- if 'type' not in value:
- msg = f'No type has been specified for node with id={key}, uri={uri}, nodes must have a type.'
- raise KeyError(msg)
- obj = self.__dict__[key] = _BaseObject(uri, **value)
- obj._id = key
- obj._uri = uri.lstrip('/')
- obj._type = value['type']
- else:
- self.__dict__[key] = value
- @property
- def id(self):
- return self._id
- @property
- def uri(self):
- return self._uri
- @property
- def type(self):
- return self._type
- @property
- def config(self):
- return self._config
- @property
- def parent(self):
- return self._parent
- @parent.setter
- def parent(self, value):
- self._parent = value
- @property
- def nodes(self):
- kids = {}
- for _id, node in self.__dict__.items():
- if isinstance(node, _BaseObject) and _id == node.id:
- kids[_id] = node
- return kids
- @property
- def has_nodes(self):
- return len(self.nodes)
- def get(self, *args):
- if args[0] is None:
- return self
- def walk(_parent, target):
- uri_parts = target.split('/')
- _id = uri_parts[0]
- if len(uri_parts) == 1 and f'{_parent.uri}/{_id}' == uri and hasattr(_parent, _id):
- return getattr(_parent, _id)
- elif hasattr(_parent, _id):
- node = getattr(_parent, _id)
- if node.uri == uri:
- return node
- else:
- uri_parts.pop(0)
- return walk(node, '/'.join(uri_parts).lstrip('/'))
- else:
- return default
- uri = args[0].lstrip('/')
- if not hasattr(self.parent, 'parent'):
- parent = self
- else:
- uri = f'{self.uri}/{uri}'
- parent = self.get_window().parent
- parts = uri.split('/', 1)
- default = None if len(args) < 2 else args[1]
- if len(parts) == 1:
- if parts[0] in self.nodes:
- return self.nodes[parts[0]]
- else:
- raise KeyError(f'Object with id = "{parts[0]}", could not be found.')
- if not parts[0] in parent.nodes:
- raise KeyError(f'Object with id = "{parts[0]}", could not be found.')
- return walk(parent.nodes[parts[0]], parts[1])
- def set(self, key, value):
- parts = key.split('/')
- if len(parts) > 1:
- attribute = parts.pop()
- uri = f'{self.uri}/{"/".join(parts)}'
- parent = self.get_window().parent.get(uri)
- else:
- parent = self
- attribute = key
- setattr(parent, attribute, value)
- def dump(self, indent=None):
- indent = indent if indent else ''
- def walkit(nodes, count=0):
- for node in nodes.values():
- if isinstance(node, _BaseObject):
- print(indent * count, node.id, node)
- walkit(node.nodes, count+1)
- walkit(self.nodes)
- def get_group(self):
- def walk(node):
- if hasattr(node, 'parent'):
- if 'Group' in node.type:
- return node
- return walk(node.parent)
- return walk(self)
- def get_widget(self):
- def walk(node):
- if hasattr(node, 'parent'):
- if 'Widget' in node.type:
- return node
- return walk(node.parent)
- return walk(self)
- def get_window(self):
- def walk(node):
- if 'Window' in node.type:
- return node
- return walk(node.parent)
- return walk(self)
- def get_attribute(self, *args):
- if not args:
- return
- if hasattr(self, args[0]):
- return getattr(self, args[0])
- elif len(args) > 1:
- return args[1]
- return None
- def set_attribute(self, attribute, value):
- setattr(self, attribute, value)
- class MyObject(_BaseObject):
- def __init__(self, uri='', **config):
- super().__init__(uri, **config)
- def walk(parent):
- for i, j in parent.nodes.items():
- j.parent = parent
- if j.has_nodes:
- walk(j)
- walk(self)
- def main():
- config = {
- 'main': {
- 'title': 'My Window',
- 'type': 'Window',
- 'bd': 10,
- 'relief': 'raised',
- 'themed': True,
- 'bg': 'green',
- 'sticky': 'nsew',
- 'tooltip': 'Testing 123...',
- 'top': {
- 'type': 'LabelGroup',
- 'text': ' Location ',
- 'bg': 'gray',
- 'widget': {
- 'type': 'Widget',
- 'label': {
- 'type': 'Label',
- 'bg': 'gray',
- 'text': 'Entry Label ',
- 'sticky': 'ne',
- 'tooltip': 'Tooltip Combobox Label'
- },
- 'group': {
- 'type': 'LabelGroup',
- 'text': ' Location ',
- 'bg': 'gray',
- 'widget': {
- 'type': 'Widget',
- 'label': {
- 'text': 'Entry Label ',
- 'sticky': 'ne',
- 'tooltip': 'Tooltip Combobox Label'
- },
- },
- },
- },
- },
- },
- }
- obj = MyObject(**config)
- print()
- obj.dump(indent='..')
- print()
- e = obj.get('/main')
- print('Window Title:', e.get('title'))
- e = obj.get('/main/top/widget/group/widget/label')
- print('color before', e.get_attribute('bg'))
- e.set_attribute('bg', 'orange')
- print('color after', e.get_attribute('bg'))
- print('color accessed by dot notation >', obj.main.top.widget.group.widget.label.bg)
- print('access top level window by dot notation >', e.parent.parent.parent.parent.parent.id)
- print('access top level window by property method >', e.get_window().id, e.get_window().parent.id)
- print('access parent group by property method >', e.get_group().id, e.get_group().type)
- print('access parent widget by property method >', e.get_widget().id, e.get_widget().type)
- print()
- print('Target:', e.id, e.type, e.uri)
- print('Background:', e.get_attribute('bg'))
- e.set('bg', 'green')
- print('Background:', e.get_attribute('bg'))
- e = obj.get('/main/top/widget/group')
- e.set('widget/label/bg', 'brown')
- print('Get background from URI method:', e.get('widget/label/bg'))
- print('Get background from Dot method:', obj.main.top.widget.group.widget.label.bg)
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement