-
Notifications
You must be signed in to change notification settings - Fork 0
/
enums.py
138 lines (101 loc) · 3.99 KB
/
enums.py
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
# -*- coding: utf-8 -*-
class AEnum (object):
_values = {}
def __new__(cls, *iterable): # итератор двойных итераторов
id=1
for it in iterable:
AEnum._values[id]=it
id <<= 1
return tuple.__new__(cls, AEnum._values.keys())
def __init__(self, *keys): # итератор двойных итераторов
self.values = AEnum._values.copy()
AEnum._values = {}
super(AEnum, self).__init__(keys)
# при запросе несуществующих атрибутов
def __getattr__(self, attr):
if attr in self.values.values():
return 1<<self.values.values().index(attr) # 2**
else:
raise Exception('called enum-object has no the attr called'
+' \"'+str(attr)+'\" and has no the value named \"'+str(attr)+'\"')
def __getitem__(self, key):
if key in self.values.keys():
return self.values[key]
else:
return self.__getattr__(key)
def __iter__(self):
for item in self.values.items():
yield item
def __str__(self):
return super(AEnum, self).__repr__()
def __repr__(self):
#
return str(self.__sum__())
def __sum__(self):
# выведет сумму индексов
r = 0
for i in self.values:
r |= i
return r
class Enum (AEnum, tuple):
def __call__(self, arg):
lb = []
i=0
r=''
for i in range(len(self)):
b = (arg >> i) & 1
lb.append(b)
if b:
r += ('|' if len(r) > 0 else '') + self[1<<i]
#print '{0} for {1}'.format(self[1<<i],i+1)
#return r
return _Enum(self, arg)
def Optional(self, func):
# специальные требования, или условия для изменения значения
if callable(func):
self.optional = func
return self
"""
Этот экз-р не должен создаваться явно. Только через Enum
"""
class _Enum(AEnum, list):
def __new__(cls, *_enum):
enum, arg = _enum # итератор двойных итераторов
if hasattr(enum, 'optional'):
if enum.optional(arg) == False:
raise Exception('the condition specified in the "Optional" is not met')
for i in range(len(enum)):
b = (arg >> i) & 1
if b:
flag = 1<<i
AEnum._values[flag] = enum[flag] #lb.append((i, enum[1<<i]))
return list.__new__(cls, AEnum._values.keys())
def __init__(self, *args): # итератор двойных итераторов
enum, arg = args
self.value = arg # итератор двойных итераторов
self.values = {}
for i in range(len(enum)):
bit = (arg >> i) & 1
if bit:
flag = 1<<i
self.values[flag] = enum[flag]
super(_Enum, self).__init__(*self.values.keys())
def __str__(self):
for i in self:
print i
return super(_Enum, self).__str__()
def __eq__(self, other):
if type(other) == str:
if other in self.values.values():
return True
else:
return False
elif type(other) == int:
return self.__sum__() == other
else:
return super(_Enum,self).__eq__(other)
def __call__(self):
r=''
for i in self.values:
r += ('|' if len(r) > 0 else '') + self[i]
return r