File: __init__.py

package info (click to toggle)
python-orderedattrdict 1.6.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 128 kB
  • sloc: python: 319; makefile: 4
file content (79 lines) | stat: -rw-r--r-- 2,765 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
'An ordered dictionary with attribute-style access.'

from collections import OrderedDict, Counter, defaultdict

# Python 3.5 does not allow inheriting from both OrderedDict and defaultdict.
# So we replace the default C implementation of OrderedDict with a pure Python
# version that's available in Python 3.5.
try:
    class _test_multi_inheritance(OrderedDict, defaultdict):
        pass
    del _test_multi_inheritance
except TypeError:
    from .ordereddict import OrderedDict


class AttrDict(OrderedDict):
    '''
    AttrDict extends OrderedDict to provide attribute-style access.

    Items starting with __ or _OrderedDict__ can't be accessed as attributes.
    '''
    __exclude_keys__ = set()

    def __getattr__(self, name):
        '''Getting ad.x gets ad["x"]'''
        if (name.startswith('__') or name.startswith('_OrderedDict__') or
                name in self.__exclude_keys__):
            return super(AttrDict, self).__getattr__(name)
        else:
            try:
                return self[name]
            except KeyError:
                raise AttributeError(name)

    def __setattr__(self, name, value):
        '''Setting ad.x sets ad["x"]'''
        if (name.startswith('__') or name.startswith('_OrderedDict__') or
                name in self.__exclude_keys__):
            return super(AttrDict, self).__setattr__(name, value)
        self[name] = value

    def __delattr__(self, name):
        '''Deleting ad.x deletes ad["x"]'''
        if (name.startswith('__') or name.startswith('_OrderedDict__') or
                name in self.__exclude_keys__):
            return super(AttrDict, self).__delattr__(name)
        del self[name]

    def __str__(self):
        '''Print like a dict that is human readable'''
        return '{' + ', '.join('%r: %r' % (key, val) for key, val in self.items()) + '}'


class CounterAttrDict(AttrDict, Counter):
    '''
    A Counter with ordered keys and attribute-style access
    '''
    def __init__(self, *args, **kwargs):
        super(AttrDict, self).__init__(*args, **kwargs)
        super(Counter, self).__init__(*args, **kwargs)
        self.__exclude_keys__ |= {'most_common', 'elements', 'subtract'}


class DefaultAttrDict(AttrDict, defaultdict):
    '''
    A defaultdict with ordered keys and attribute-style access.
    '''
    def __init__(self, default_factory, *args, **kwargs):
        super(AttrDict, self).__init__(*args, **kwargs)
        defaultdict.__init__(self, default_factory)
        self.__exclude_keys__ |= {'default_factory', '_ipython_display_'}


class Tree(DefaultAttrDict):
    '''
    A tree structure that lets you set attributes at any level.
    '''
    def __init__(self, *args, **kwargs):
        super(Tree, self).__init__(Tree, *args, **kwargs)