Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

# -*- coding: utf-8 -*- 

""" 

AttribDict class for ObsPy. 

 

:copyright: 

    The ObsPy Development Team (devs@obspy.org) 

:license: 

    GNU Lesser General Public License, Version 3 

    (http://www.gnu.org/copyleft/lesser.html) 

""" 

 

import collections 

import copy 

 

 

class AttribDict(collections.MutableMapping): 

    """ 

    A class which behaves like a dictionary. 

 

    :type data: dict, optional 

    :param data: Dictionary with initial keywords. 

 

    .. rubric:: Basic Usage 

 

    You may use the following syntax to change or access data in this class. 

 

    >>> stats = AttribDict() 

    >>> stats.network = 'BW' 

    >>> stats['station'] = 'ROTZ' 

    >>> stats.get('network') 

    'BW' 

    >>> stats['network'] 

    'BW' 

    >>> stats.station 

    'ROTZ' 

    >>> x = stats.keys() 

    >>> x = sorted(x) 

    >>> x[0:3] 

    ['network', 'station'] 

    """ 

    defaults = {} 

    readonly = [] 

 

    def __init__(self, *args, **kwargs): 

        """ 

        An AttribDict can be initialized in two ways. It can be given an 

        existing dictionary as a simple argument or alternatively all keyword 

        arguments will become (key, value) pairs. 

 

        >>> attrib_dict_1 = AttribDict({"a":1, "b":2}) 

        >>> attrib_dict_2 = AttribDict(a=1, b=2) 

        >>> print attrib_dict_1 

        AttribDict({'a': 1, 'b': 2}) 

        >>> assert(attrib_dict_1 == attrib_dict_2) 

        """ 

        # set default values directly 

        self.__dict__.update(self.defaults) 

        # use overwritable update method to set arguments 

        self.update(dict(*args, **kwargs)) 

 

    def __repr__(self): 

        return "%s(%s)" % (self.__class__.__name__, self.__dict__) 

 

    def __getitem__(self, name, default=None): 

        try: 

            return self.__dict__[name] 

        except KeyError: 

            # check if we got any default value given at class level 

            if name in self.defaults: 

                return self.defaults[name] 

            # if both are missing check for a given default value 

            if default is None: 

                raise 

            return default 

 

    def __setitem__(self, key, value): 

        if key in self.readonly: 

            msg = 'Attribute "%s" in %s object is read only!' 

            raise AttributeError(msg % (key, self.__class__.__name__)) 

        self.__dict__[key] = value 

 

    def __delitem__(self, name): 

        del self.__dict__[name] 

 

    def __getstate__(self): 

        return self.__dict__ 

 

    def __setstate__(self, adict): 

        # set default values 

        self.__dict__.update(self.defaults) 

        # update with pickle dictionary 

        self.update(adict) 

 

    __getattr__ = __getitem__ 

    __setattr__ = __setitem__ 

    __delattr__ = __delitem__ 

 

    def copy(self): 

        return copy.deepcopy(self) 

 

    def __deepcopy__(self, *args, **kwargs):  # @UnusedVariable 

        ad = self.__class__() 

        ad.update(copy.deepcopy(self.__dict__)) 

        return ad 

 

    def update(self, adict={}): 

        for (key, value) in adict.iteritems(): 

            if key in self.readonly: 

                continue 

            self.__setitem__(key, value) 

 

    def _pretty_str(self, priorized_keys=[], min_label_length=16): 

        """ 

        Return better readable string representation of AttribDict object. 

 

        :type priorized_keys: List of str, optional 

        :param priorized_keys: Keywords of current AttribtDict which will be 

            shown before all other keywords. Those keywords must exists 

            otherwise an exception will be raised. Defaults to empty list. 

        :type min_label_length: int, optional 

        :param min_label_length: Minimum label length for keywords. Defaults 

            to ``16``. 

        :return: String representation of current AttribDict object. 

        """ 

        keys = self.keys() 

        # determine longest key name for alignment of all items 

        try: 

            i = max(max([len(k) for k in keys]), min_label_length) 

        except ValueError: 

            # no keys 

            return "" 

        pattern = "%%%ds: %%s" % (i) 

        # check if keys exist 

        other_keys = [k for k in keys if k not in priorized_keys] 

        # priorized keys first + all other keys 

        keys = priorized_keys + sorted(other_keys) 

        head = [pattern % (k, self.__dict__[k]) for k in keys] 

        return "\n".join(head) 

 

    def __iter__(self): 

        return iter(self.__dict__) 

 

    def __len__(self): 

        return len(self.__dict__) 

 

 

if __name__ == '__main__': 

    import doctest 

    doctest.testmod(exclude_empty=True)