m2m模型翻译
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

157 lines
5.9 KiB

# Human friendly input/output in Python.
#
# Author: Peter Odding <peter@peterodding.com>
# Last Change: April 19, 2020
# URL: https://humanfriendly.readthedocs.io
"""
Simple case insensitive dictionaries.
The :class:`CaseInsensitiveDict` class is a dictionary whose string keys
are case insensitive. It works by automatically coercing string keys to
:class:`CaseInsensitiveKey` objects. Keys that are not strings are
supported as well, just without case insensitivity.
At its core this module works by normalizing strings to lowercase before
comparing or hashing them. It doesn't support proper case folding nor
does it support Unicode normalization, hence the word "simple".
"""
# Standard library modules.
import collections
try:
# Python >= 3.3.
from collections.abc import Iterable, Mapping
except ImportError:
# Python 2.7.
from collections import Iterable, Mapping
# Modules included in our package.
from humanfriendly.compat import basestring, unicode
# Public identifiers that require documentation.
__all__ = ("CaseInsensitiveDict", "CaseInsensitiveKey")
class CaseInsensitiveDict(collections.OrderedDict):
"""
Simple case insensitive dictionary implementation (that remembers insertion order).
This class works by overriding methods that deal with dictionary keys to
coerce string keys to :class:`CaseInsensitiveKey` objects before calling
down to the regular dictionary handling methods. While intended to be
complete this class has not been extensively tested yet.
"""
def __init__(self, other=None, **kw):
"""Initialize a :class:`CaseInsensitiveDict` object."""
# Initialize our superclass.
super(CaseInsensitiveDict, self).__init__()
# Handle the initializer arguments.
self.update(other, **kw)
def coerce_key(self, key):
"""
Coerce string keys to :class:`CaseInsensitiveKey` objects.
:param key: The value to coerce (any type).
:returns: If `key` is a string then a :class:`CaseInsensitiveKey`
object is returned, otherwise the value of `key` is
returned unmodified.
"""
if isinstance(key, basestring):
key = CaseInsensitiveKey(key)
return key
@classmethod
def fromkeys(cls, iterable, value=None):
"""Create a case insensitive dictionary with keys from `iterable` and values set to `value`."""
return cls((k, value) for k in iterable)
def get(self, key, default=None):
"""Get the value of an existing item."""
return super(CaseInsensitiveDict, self).get(self.coerce_key(key), default)
def pop(self, key, default=None):
"""Remove an item from a case insensitive dictionary."""
return super(CaseInsensitiveDict, self).pop(self.coerce_key(key), default)
def setdefault(self, key, default=None):
"""Get the value of an existing item or add a new item."""
return super(CaseInsensitiveDict, self).setdefault(self.coerce_key(key), default)
def update(self, other=None, **kw):
"""Update a case insensitive dictionary with new items."""
if isinstance(other, Mapping):
# Copy the items from the given mapping.
for key, value in other.items():
self[key] = value
elif isinstance(other, Iterable):
# Copy the items from the given iterable.
for key, value in other:
self[key] = value
elif other is not None:
# Complain about unsupported values.
msg = "'%s' object is not iterable"
type_name = type(value).__name__
raise TypeError(msg % type_name)
# Copy the keyword arguments (if any).
for key, value in kw.items():
self[key] = value
def __contains__(self, key):
"""Check if a case insensitive dictionary contains the given key."""
return super(CaseInsensitiveDict, self).__contains__(self.coerce_key(key))
def __delitem__(self, key):
"""Delete an item in a case insensitive dictionary."""
return super(CaseInsensitiveDict, self).__delitem__(self.coerce_key(key))
def __getitem__(self, key):
"""Get the value of an item in a case insensitive dictionary."""
return super(CaseInsensitiveDict, self).__getitem__(self.coerce_key(key))
def __setitem__(self, key, value):
"""Set the value of an item in a case insensitive dictionary."""
return super(CaseInsensitiveDict, self).__setitem__(self.coerce_key(key), value)
class CaseInsensitiveKey(unicode):
"""
Simple case insensitive dictionary key implementation.
The :class:`CaseInsensitiveKey` class provides an intentionally simple
implementation of case insensitive strings to be used as dictionary keys.
If you need features like Unicode normalization or proper case folding
please consider using a more advanced implementation like the :pypi:`istr`
package instead.
"""
def __new__(cls, value):
"""Create a :class:`CaseInsensitiveKey` object."""
# Delegate string object creation to our superclass.
obj = unicode.__new__(cls, value)
# Store the lowercased string and its hash value.
normalized = obj.lower()
obj._normalized = normalized
obj._hash_value = hash(normalized)
return obj
def __hash__(self):
"""Get the hash value of the lowercased string."""
return self._hash_value
def __eq__(self, other):
"""Compare two strings as lowercase."""
if isinstance(other, CaseInsensitiveKey):
# Fast path (and the most common case): Comparison with same type.
return self._normalized == other._normalized
elif isinstance(other, unicode):
# Slow path: Comparison with strings that need lowercasing.
return self._normalized == other.lower()
else:
return NotImplemented