27 Star 84 Fork 32

Jone.x / oejia_weshop

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
const.py 5.62 KB
一键复制 编辑 原始数据 按行查看 历史
Jone.x 提交于 2018-09-17 20:49 . fix
# -*- coding: utf-8 -*-
import copy
import warnings
from types import GeneratorType
import six
class SortedDict(dict):
"""
A dictionary that keeps its keys in the order in which they're inserted.
"""
def __new__(cls, *args, **kwargs):
instance = super(SortedDict, cls).__new__(cls, *args, **kwargs)
instance.keyOrder = []
return instance
def __init__(self, data=None):
if data is None:
data = {}
elif isinstance(data, GeneratorType):
# Unfortunately we need to be able to read a generator twice. Once
# to get the data into self with our super().__init__ call and a
# second time to setup keyOrder correctly
data = list(data)
super(SortedDict, self).__init__(data)
if isinstance(data, dict):
self.keyOrder = list(data)
else:
self.keyOrder = []
seen = set()
for key, value in data:
if key not in seen:
self.keyOrder.append(key)
seen.add(key)
def __deepcopy__(self, memo):
return self.__class__([(key, copy.deepcopy(value, memo))
for key, value in self.iteritems()])
def __copy__(self):
# The Python's default copy implementation will alter the state
# of self. The reason for this seems complex but is likely related to
# subclassing dict.
return self.copy()
def __setitem__(self, key, value):
if key not in self:
self.keyOrder.append(key)
super(SortedDict, self).__setitem__(key, value)
def __delitem__(self, key):
super(SortedDict, self).__delitem__(key)
self.keyOrder.remove(key)
def __iter__(self):
return iter(self.keyOrder)
def pop(self, k, *args):
result = super(SortedDict, self).pop(k, *args)
try:
self.keyOrder.remove(k)
except ValueError:
# Key wasn't in the dictionary in the first place. No problem.
pass
return result
def popitem(self):
result = super(SortedDict, self).popitem()
self.keyOrder.remove(result[0])
return result
def _iteritems(self):
for key in self.keyOrder:
yield key, self[key]
def _iterkeys(self):
for key in self.keyOrder:
yield key
def _itervalues(self):
for key in self.keyOrder:
yield self[key]
iteritems = _iteritems
iterkeys = _iterkeys
itervalues = _itervalues
def items(self):
return list(self.iteritems())
def keys(self):
return list(self.iterkeys())
def values(self):
return list(self.itervalues())
def update(self, dict_):
for k, v in six.iteritems(dict_):
self[k] = v
def setdefault(self, key, default):
if key not in self:
self.keyOrder.append(key)
return super(SortedDict, self).setdefault(key, default)
def value_for_index(self, index):
"""Returns the value of the item at the given zero-based index."""
# This, and insert() are deprecated because they cannot be implemented
# using collections.OrderedDict (Python 2.7 and up), which we'll
# eventually switch to
warnings.warn(
"SortedDict.value_for_index is deprecated", PendingDeprecationWarning,
stacklevel=2
)
return self[self.keyOrder[index]]
def insert(self, index, key, value):
"""Inserts the key, value pair before the item with the given index."""
warnings.warn(
"SortedDict.insert is deprecated", PendingDeprecationWarning,
stacklevel=2
)
if key in self.keyOrder:
n = self.keyOrder.index(key)
del self.keyOrder[n]
if n < index:
index -= 1
self.keyOrder.insert(index, key)
super(SortedDict, self).__setitem__(key, value)
def copy(self):
"""Returns a copy of this object."""
# This way of initializing the copy means it works for subclasses, too.
return self.__class__(self)
def __repr__(self):
"""
Replaces the normal dict.__repr__ with a version that returns the keys
in their sorted order.
"""
return '{%s}' % ', '.join(['%r: %r' % (k, v) for k, v in self.iteritems()])
def clear(self):
super(SortedDict, self).clear()
self.keyOrder = []
class ConstType(type):
def __new__(cls, name, bases, attrs):
attrs_value = {}
attrs_label = {}
new_attrs = {}
labels_to_values = {}
for k, v in attrs.items():
if k.startswith('__'):
continue
if isinstance(v, tuple):
attrs_value[k] = v[0]
attrs_label[k] = v[1]
new_attrs[v[0]] = v[1]
labels_to_values[v[1]] = v[0]
elif isinstance(v, dict) and 'label' in v:
attrs_value[k] = v['value']
attrs_label[k] = v['label']
labels_to_values[v['label']] = v['value']
new_attrs[v['value']] = v['label']
else:
attrs_value[k] = v
attrs_label[k] = v
sort_new_attrs = sorted(six.iteritems(new_attrs), key=lambda kv: k[0])
new_attrs = SortedDict(sort_new_attrs)
obj = type.__new__(cls, name, bases, attrs_value)
obj.values = attrs_value
obj.labels = attrs_label
obj.labels_to_values = labels_to_values
obj.attrs = new_attrs
return obj
class Const(six.with_metaclass(ConstType)):
pass
Python
1
https://gitee.com/jone/oejia_weshop.git
git@gitee.com:jone/oejia_weshop.git
jone
oejia_weshop
oejia_weshop
master

搜索帮助