Oto pomysł dla podklasy dict, która może mutować klucze. Jest to prosty samodzielny przykład, który jest podobny do dict
, ale jest niewrażliwy na wielkość liter dla kluczy str
.Dlaczego mój pomysł nie działa w python2?
from functools import wraps
def key_fix_decorator(f):
@wraps(f)
def wrapped(self, *args, **kwargs):
if args and isinstance(args[0], str):
args = (args[0].lower(),) + args[1:]
return f(self, *args, **kwargs)
return wrapped
class LowerDict(dict):
pass
for method_name in '__setitem__', '__getitem__', '__delitem__', '__contains__', 'get', 'pop', 'setdefault':
new_method = key_fix_decorator(getattr(LowerDict, method_name))
setattr(LowerDict, method_name, new_method)
dev note: jeśli kopia mojego kodu do własnych zastosowań, należy wdrożyć LowerDict.__init__
celu wykrycia kolizji kluczowych - Nie przejmowałem się to, że dla celów tego pytania
na python3 to wszystko wydaje się działa dobrze:
>>> d = LowerDict(potato=123, spam='eggs')
>>> d['poTATo']
123
>>> d.pop('SPAm')
'eggs'
>>> d['A']
# KeyError: 'a'
W python2 to nawet nie import, tutaj jest traceback:
File "/tmp/thing.py", line 15, in <module>
new_method = key_fix_decorator(getattr(LowerDict, method_name))
File "/tmp/thing.py", line 4, in key_fix_decorator
@wraps(f)
File "/usr/lib/python2.7/functools.py", line 33, in update_wrapper
setattr(wrapper, attr, getattr(wrapped, attr))
AttributeError: 'wrapper_descriptor' object has no attribute '__module__'
Jaki może być problem? Nie widzę żadnego kodu specyficznego dla wersji z wyjątkiem przypadku str
/basestring
, który jest tylko drobnym szczegółem, a nie problemem z łamaniem kodów.
Różnica polega na tym, w jaki sposób implementowany jest "update_wrapper" w obu wersjach.https: //hg.python.org/cpython/file/2.7/Lib/functools.py#l17 i https://hg.python.org/ cpython/file/3.4/Lib/functools.py # l43 –
Jest to prawdopodobnie powiązane: http://bugs.python.org/issue3445 –
Możesz być także zainteresowany PEP 455: https://www.python.org/ dev/peps/pep-0455 / –