Skip to main content
Help us improve PyPI by participating in user testing. All experience levels needed!

A Python dict subclass which tries to act like JavaScript objects, so you can use the dot-notation (d.foo) to access members of the object.

Project description

A Python dict subclass which tries to act like JavaScript objects, so you can use the dot notation (d.foo) to access members of the object. If the member doesn’t exist yet then it’s created when you assign a value to it. Brackets notation (d[‘foo’]) is also possible.

Installation

$ pip install mydict

Examples

Let’s give it a try

d = MyDict()
d.foo = 'bar'

print(d.foo)
# ==> 'bar'

If you try to get the value of a non-existing member then a None value is returned

d = MyDict()
if d.foo is None:
    print('"foo" does not exist yet!')

If that value is “complex” (a dict or another MyDict instance), then it’s also recursively transformed into a MyDict object, so you can access it in the same way

d = MyDict()
d.foo = {'bar': 'baz', 'lst': [{'a': 123}]}

print(d.foo.bar)
# ==> 'baz'

print(d.foo.bar)
# ==> 'baz'

print(d.foo.lst[0].a)
# ==> 123

Values in lists are accessed, as you expect, with the brackets notation (d[0]):

d = MyDict()
d.foo = [1, 2, 3]

print(d.foo[2])
# ==> 3

We can instantiate it from a dict of any level of complexity

d = MyDict({'foo': 'bar', 'baz': [1, 2, {'foo': 'bar', 'baz': 'Hello, world!'}}])

print(d.foo)
# ==> 'bar'

print(d.baz[0])
# ==> 1

print(d.baz[2].foo)
# ==> 'bar'

with keywords in the constructor

d = MyDict(a=1, b=2.2, c=[1, 2, 3], d=[{'x': 1, 'y': [100, 200, 300]}])
...
d.a == 1
d.b == 2.2
d.c[0] == 1
d.d[0].x == 1
d.d[0].y[1] == 200

or both

d = MyDict({'foo': 'bar'}, baz=123)
...
d.foo == 'bar'
d.baz == 123

Please, take into account that keyword initialization has precedence over the dict (first parameter of the constructor)

d = MyDict({'foo': 'bar'}, foo='BAR')
...
d.foo == 'BAR'

It’s also possible to access members using a path with get or brackets notation (d[‘…’]):

d = MyDict(foo={'bar': 'baz'})
...
d['foo.bar'] == 'baz'
d.get('foo.bar') == 'baz'

But when those keys with dots exists in the tree they are accessed using the corresponding key

d = MyDict({'foo.bar': 'baz'})
...
# 'foo.bar' is not interpreted as a path because the key exists
d['foo.bar'] = 'baz'

But there’s a particular case, if a dotted key exists and match an existing path, then this ain’t work properly, or work in a different way depending on the method of access used, to be correct

d = MyDict({'foo': {'bar': 'baz'}, 'foo.bar': 'BAZ'})
...
d['foo.bar'] = 'BAZ'  # the "dotted field" ('foo.bar') has precedence over the path
d.foo.bar = 'baz'  # it's not possible to detect a "dotted key" using "dot notation"

Personally, I don’t see this as a great issue because I generally avoid using dots in keys, like in the previous case

Initialization from JSON

It’s also possible to load a JSON from str, bytes, and file-like objects (with a .read() method) using the static method from_json:

d = MyDict.from_json('{"foo": "bar"}')
# d.foo == 'bar'


d = MyDict.from_json(b'{"foo": "bar"}')
# d.foo == 'bar'


d = MyDict.from_json(open('/path/to/file.json', 'r'))
# d = MyDict.from_json(open('/path/to/file.json', 'rb')) also work


from io import StringIO, BytesIO

s = StringIO()
s.write('{"foo": "bar"}')

d = MyDict.from_json(s)
# d.foo == 'bar'

...

b = StringIO()
b.write(b'{"foo": "bar"}')

d = MyDict.from_json(b)
# d.foo == 'bar'

The tests passed successfully with Python 3.6. With Python 2.7 failed on “bytes stuff” tests, regarding the use of the static method “from_json()”

$ pytest mydict -v

Project details


Release history Release notifications

This version
History Node

1.0.14

History Node

1.0.13

History Node

1.0.12

History Node

1.0.11

History Node

1.0.10

History Node

1.0.9

History Node

1.0.8

History Node

1.0.7

History Node

1.0.6

History Node

1.0.5

History Node

1.0.4

History Node

1.0.3

History Node

1.0.2

History Node

1.0.1

History Node

1.0.0

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Filename, size & hash SHA256 hash help File type Python version Upload date
mydict-1.0.14-py2.py3-none-any.whl (8.4 kB) Copy SHA256 hash SHA256 Wheel 3.6 Aug 6, 2017
mydict-1.0.14.tar.gz (5.3 kB) Copy SHA256 hash SHA256 Source None Aug 6, 2017

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging CloudAMQP CloudAMQP RabbitMQ AWS AWS Cloud computing Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page