Go deh!

Mainly Tech projects on Python and Electronic Design Automation.

Sunday, May 26, 2019

Nested attribute lookup in dicts

As part of a larger project, I wanted to explore the use of Python object  attribute access syntax to access items of a dict.

A base.

I looked around and found this article that gave me a base I could riff off. I want the attributes accessed to appear in the dictionary. I want nested attribut access to "work".

A new implementation.

I came up with the following code. any attributes starting with an underscore are excused from jiggery-pokery as Spyder/Ipython sets a few.

class AttrInDict(dict):
    "Move none-hidden attribute access to dict item"
 
    def __init__(self, *args, **kwargs):
        self._extra_attr = set()
        super().__init__(*args, **kwargs)
 
    def __getattr__(self, item):
        if item[0] != '_':
            if (not super().__contains__(item)  # Its new
                or (item in self._extra_attr    # It's an attr, now None
                    and super().__getitem__(item) is None)):
                super().__setitem__(item, AttrInDict())
            return super().__getitem__(item)
        else:
            return super().__getattr__(item)
 
    def __setattr__(self, item, val):
        if item[0] != '_':
            super().__setitem__(item, val)
            self._extra_attr.add(item)
        else:
            super().__setattr__(item, val)
 
    def __dir__(self):
        "To get tooltips working"
        supr = set(super().__dir__())
        return list(supr | self._extra_attr)


Class in action.

Python 3.7.1 | packaged by conda-forge | (default, Mar 13 2019, 13:32:59) [MSC v.1900 64 bit (AMD64)]
Type "copyright", "credits" or "license" for more information.

IPython 7.1.1 -- An enhanced Interactive Python.

Restarting kernel...



In [1]: runfile('dictindict.py', wdir='pp_reg')

In [2]: # Start like a dict

In [3]: d = AttrInDict(x=3)

In [4]: d
Out[4]: {'x': 3}

In [5]: # Access like an attribute

In [6]: d.x
Out[6]: 3

In [7]: # Access an unknown attribute creates a sub-"dict"

In [8]: d.foo
Out[8]: {}

In [9]: d
Out[9]: {'x': 3, 'foo': {}}

In [10]: d.foo = 123

In [11]: d.foo
Out[11]: 123

In [12]: d
Out[12]: {'x': 3, 'foo': 123}

In [13]: # Access an unknown, unknown attribute creates sub, sub "dicts"

In [14]: d.tick.tock
Out[14]: {}

In [15]: d
Out[15]: {'x': 3, 'foo': 123, 'tick': {'tock': {}}}

In [16]: # Dict hierarchy preserved

In [17]: d.tick.tack = 22

In [18]: d
Out[18]: {'x': 3, 'foo': 123, 'tick': {'tock': {}, 'tack': 22}}

In [19]: d.tick.teck = 33

In [20]: d
Out[20]: {'x': 3, 'foo': 123, 'tick': {'tock': {}, 'tack': 22, 'teck': 33}}

In [21]: d.tick.tock.tuck = 'Boo'

In [22]: d
Out[22]: {'x': 3, 'foo': 123, 'tick': {'tock': {'tuck': 'Boo'}, 'tack': 22, 'teck': 33}}

In [23]: # Can tack on hierarchy to previous attribute with None value

In [24]: d.foo = None

In [25]: d
Out[25]:
{'x': 3,
'foo': None,
'tick': {'tock': {'tuck': 'Boo'}, 'tack': 22, 'teck': 33}}

In [26]: d.foo.bar = 42

In [27]: d
Out[27]:
{'x': 3,
'foo': {'bar': 42},
'tick': {'tock': {'tuck': 'Boo'}, 'tack': 22, 'teck': 33}}

In [28]: # Still like a dict

In [29]: d.keys()
Out[29]: dict_keys(['x', 'foo', 'tick'])

In [30]: d.values()
Out[30]: dict_values([3, {'bar': 42}, {'tock': {'tuck': 'Boo'}, 'tack': 22, 'teck': 33}])

In [31]:

END.

Friday, October 12, 2018

Three guys on math



Coder:

    (In Jeans and T-shirt, next to a cup of coffee) I look down on him (Indicates Excel'r) because I write proper programs.

Excel'r:

    (Trousers, shirt, no tie) I look up to him (Coder) because he writes proper programs; but I look down on him (Hand-Calculater) because he has no graphics. I have a GUI

Hand-Calculater:

    (Student) I know my place. I look up to them both. But I don't look up to him (Excel'r) as much as I look up to him (Coder), because he writes apps and games.

Coder:

    I do write apps and games, but I have a higher barrier to entry. So sometimes I look up (bends knees, does so) to him (Excel'r).

Excel'r:

    I still look up to him (Coder) because although I have easy access, I am vulgar. But I am not as vulgar as him (Hand-Calculater) so I still look down on him (Hand-Calculater).

Hand-Calculater:

    I know my place. I look up to them both; but while I am poor, I am honest, industrious and trustworthy. Had I the inclination, I could look down on them. But I don't.

Excel'r:

    We all know our place, but what do we get out of it?

Coder:

    I get a feeling of superiority over them.

Excel'r:

    I get a feeling of inferiority from him, (Coder), but a feeling of superiority over him (Hand-Calculater).

Hand-Calculater:

    I get RSI.


Original Sketch:


Thursday, August 23, 2018

Python PyPy interpreter in Javascript: Chrome and Edge beat firefox!

.

Firefox 61.0.2:

 (My normal windows browser):



Firefox occasionally and erratically hit >280,000 over the next ten runs.

Chrome 68.0.3440.106 (64 bit)

(My alternate Windows browser)



Chrome usually hit >450,000 over the next ten runs.

Edge 42.17134.1.0

(My second, alternate Windows browser)




Edge consistantly hit >416,000 over the next ten runs.

Conclusion

What conclusion!
It's all a bit of fun :-)

Followers

Subscribe Now: google

Add to Google Reader or Homepage

Go deh too!

whos.amung.us

Blog Archive