Python supports well known data types, like lists and dictionaries that are easy to use. But can you cheat
interpreter to use easier semantics to access dict data?
PEP 484
introduced type hinting which was first implemented in Python 3.5. We can use it to instruct our IDE to
help us with code completion. Unfortunately it’s a bit intrusive and requires a lot of additional typing, it’s also
unavailable in older, still supported, releases.
We can use a dictionary and a few magic methods to help ourselves. Implementation in Python 3 is easier, because we
have access to abstract type MutableMapping
that expects implementation of few methods and adds many others without
any additional code (by inheriting from other classes). The complete clone in Python 2 will require a lot more code,
but the basic version can be created very easily.
In Python 3:
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
| from collections import MutableMapping
from functools import partial
from operator import add
class MagicDict(MutableMapping):
def __getitem__(self, key):
return self.__dict__[key]
def __delitem__(self, key):
del self.__dict__[key]
def __setitem__(self, key, value):
self.__dict__[key] = value
def __iter__(self):
return iter(self.__dict__)
def __len__(self):
return len(self.__dict__)
if __name__ == '__main__':
md = MagicDict()
md.data = 2+2*2
md.add_two = partial(add, 2)
print(md.add_two(md.data))
for k, v in md.items():
print("{} => {}".format(k, v))
|
will output:
1
2
3
| 8
data => 6
add_two => functools.partial(<built-in function add>, 2)
|
In Python 2:
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
| class MagicDict(object):
def __init__(self):
super(MagicDict, self).__setattr__('__dict__', {})
def __setattr__(self, key, value):
self.__dict__[key] = value
def __getattr__(self, key):
return self.__dict__[key]
def __iter__(self):
return iter(self.__dict__)
def values(self):
return self.__dict__.values()
def iteritems(self):
return self.__dict__.iteritems()
if __name__ == '__main__':
md = MagicDict()
md.data = 2+2*2
md.add_two = lambda x: x + 2
print(md.add_two(md.data))
for k, v in md.iteritems():
print("{} => {}".format(k, v))
|
will output:
1
2
3
| 8
data = > 6
add_two = > <function <lambda> at 0x10d4f8410>
|