|
|
Subscribe / Log in / New account

Improving Python's SimpleNamespace

Improving Python's SimpleNamespace

Posted Apr 30, 2020 5:12 UTC (Thu) by neilbrown (subscriber, #359)
In reply to: Improving Python's SimpleNamespace by dtlin
Parent article: Improving Python's SimpleNamespace

> Still feels pretty foreign to Python though.

I wonder what you mean by that exactly. For example, does it contravene some part of the Zen of Python?

Simple is better than complex.
Readability counts.
Now is better than never.

All seem to support it.

The article mentioned a ".." suggestion which is much like this "!" suggestion. Would ".." feel less foreign??


to post comments

Improving Python's SimpleNamespace

Posted Apr 30, 2020 6:19 UTC (Thu) by dtlin (subscriber, #36537) [Link] (17 responses)

There should be one-- and preferably only one --obvious way to do it.

Obviously there's other forms of syntactic sugar in Python. But it seems to me like other sugar has more benefit than saving 3 characters - or 2 characters, in the case of obj..abc..def..ghi. IMO obj['abc']['def']['ghi'] already scores reasonably well along simple, readable, and now measures, so a proposal should be substantially better.

Improving Python's SimpleNamespace

Posted Apr 30, 2020 7:16 UTC (Thu) by smurf (subscriber, #17840) [Link] (16 responses)

Well, I disagree. I also seem not to be the only person who has re-invented "AttrDict" (even using that exact name), so I might be a bit prejudiced.

It's also not just readability but also typing. One dot is one keystroke with pretty much any keyboard layout ever. On a German keyboard, however, [''] requires eight (brackets require AltGr while single quotes need Shift). Owch.

Typing costs of non-English keyboard layouts in programming languages

Posted Apr 30, 2020 10:42 UTC (Thu) by mbunkus (subscriber, #87248) [Link] (7 responses)

This is a real problem. I'm German like most Germans used to use German keyboard layout. A lot of years ago I had to write so much LaTeX by day (job) & C++ by night (hobby) that I developed pain in my right wrist (possibly RPI, though I never went to see a doctor). The reason is that on German keyboards you need to press AltGr (think "right Alt key" for non-German keyboard users) for all of the most often used characters in LaTeX: \ { } [ ]

Not only that, for pressing{ with one hand you really need to do funky acrobatics as it's on AltGr+7. Doing that for several hours a day _hurt_! Look at images of German keyboard layouts to get an idea how you have to contort your hand for that.

The result was that I switched to English layouts, even with German keyboards. I then spent hours on implementing some way to write German Umlauts & ß without too much hassle (I also switched to using ergonomic keyboards, but that's a different topic).

smurf is right, having to type asd['qwe']['whatever'] requires a LOT of changing states of different modifier keys, it slows down typing significantly: a s d press&hold AltGr 8 release AltGr press&hold Shift # release Shift q w e press&hold Shift # release Shift press&hold AltGr+9 etc. etc.

I'm pretty sure other non-English languages have similar problems typing something like that.

Typing costs of non-English keyboard layouts in programming languages

Posted Apr 30, 2020 14:12 UTC (Thu) by NAR (subscriber, #1313) [Link] (2 responses)

This is the reason why I use "hunglish" layout: English layout, extra Hungarian characters available by AltGr (mostly) on the right side of the keyboard (e.g. 0-=[];'\), so it's fairly easy to type them. I never understood people who can use Hungarian layout for programming... BTW Elixir has maps (the usual associative arrays) in the language. It has also structs, but those are implemented using maps with a special __struct__ field containing the type and the field names of the structs are keys in the map (as atoms). The generic syntax for accessing maps is the usual map[key], while for structs it is struct.attribute. So far so good, it's probably what people from other languages expect. However, for some reason if the keys of a map are atoms, the "struct syntax" also works - which sometimes drives me nuts as I can't tell by looking at code like this:

some.thing

that it's accessing a struct or a map. It also has an interesting interplay with command line expansion - it is possible to create atom names with space (crazy idea, but possible):

iex(8)> m3 = %{:"a b" => "c"}
%{"a b": "c"}

Then when I type m3. followed by TAB, the shell helpfully extends the field name, so I get

iex(9)> m3.a b
** (CompileError) iex:9: undefined function b/0

Of course, m3."a b" or m3[:"a b"] works.

Typing costs of non-English keyboard layouts in programming languages

Posted May 4, 2020 12:14 UTC (Mon) by ballombe (subscriber, #9523) [Link] (1 responses)

I do something similar. I stopped using X for typing when xmodmap was deprecated in favor of unusable xkb.

Typing costs of non-English keyboard layouts in programming languages

Posted May 4, 2020 12:58 UTC (Mon) by mathstuf (subscriber, #69389) [Link]

I use Xcompose settings which still seem to work even in the xkb era. `setxkbmap` is how I enable AltGr/compose keys on my layout as well. `xmodmap` seems mostly replaced with libinput these days. For example, here's how I remap Caps Lock to be Backspace:

% cat /etc/udev/99-kb-capslock.hwdb
evdev:input:b0011v0001p0001eAB41-*:
KEYBOARD_KEY_70039=backspace

which means that it also works on the TTY and not just when X is running (and apps can't sniff the fact that it is Caps Lock behind my back and do the wrong thing).

Typing costs of non-English keyboard layouts in programming languages

Posted May 1, 2020 8:03 UTC (Fri) by knuto (subscriber, #96401) [Link]

This brought back some old memories here...
Yes, same issue in Norwegian, both {} and [] requires AltGr. But when iso8859-1 emerged,
it was still an enormous a relief compared to back in the 7 bit ascii days when a construct like

\documentstyle[12pt]{report}

would show up on Norwegian screens as

ØdocumentstyleÆ12ptÅæreportå

and 'hopeless' == 'håpløst' in Norwegian
would have to be written as the less readable 'hØaaplØost'

I ended up writing a small 138 lines of c code preprocessor for TeX which I used for all my early years of TeX and subsequently LaTeX work that used /<> instead of \{} , translated all the æøå variants to the right escape sequences and an escape construct @( @) and special handling of \begin{verbatim} .. \end{verbatim}.

Typing costs of non-English keyboard layouts in programming languages

Posted May 7, 2020 22:24 UTC (Thu) by flussence (guest, #85566) [Link]

I've been using a weird mini keyboard for a few years now. Having {}[]()<> all equally awkward to reach (though thankfully none of them require one-hand chording) has really made me appreciate programming languages that offer more than one way to do it.

But now I can emphasise with the plight of users who get this experience by default. A lot of programming's still too ASCII-centric.

Typing costs of non-English keyboard layouts in programming languages

Posted May 7, 2020 23:01 UTC (Thu) by Cyberax (✭ supporter ✭, #52523) [Link] (1 responses)

Have you tried installing two keyboard layouts and switching between them (CapsLock is the best switch key)?

Typing costs of non-English keyboard layouts in programming languages

Posted May 9, 2020 16:42 UTC (Sat) by smurf (subscriber, #17840) [Link]

That's a good idea in principle – I tried, but I need to use computers where this is not possible far too often. The mental effort to switch is … painful. I positively envy people who can do that on the fly.

Improving Python's SimpleNamespace

Posted May 2, 2020 4:20 UTC (Sat) by NYKevin (subscriber, #129325) [Link] (7 responses)

One of the more interesting suggestions in that thread, from Chris Angelico:

My solution to that has usually been something along the lines of:

def get(obj, path):
    for step in path.split("-"):
        obj = obj[step]
    return obj

print(get(catalog, 'clothing-mens-shoes-extra_wide-quantity'))

Will often be custom-tweaked to the situation, but the basic idea is the same.

My 2 cents: I would much prefer forward slashes as the separator (by analogy with filesystem paths), but otherwise that looks quite reasonable to me. It also solves the foo["names with multiple words aren't valid identifiers"] problem. And as an extra bonus, this requires no changes to core Python or the standard library, and can traverse any dict-like object that supports __getitem__(), rather than being a class in its own right (no ugly multiple inheritance if you want to combine functionality with another mapping type).

Improving Python's SimpleNamespace

Posted May 2, 2020 7:12 UTC (Sat) by dtlin (subscriber, #36537) [Link] (4 responses)

Seems to me that it makes more sense to keep splitting the responsibility of the caller:

def deep_getitem(obj, *path):
    return functools.reduce(operator.getitem, path, obj)

deep_getitem(catalog, *'clothing mens shoes extra_wide quantity'.split())

The caller should know what an appropriate separator is, and could even build the path up from multiple parts split in different ways if that's appropriate.

Although that reminds me of how convenient Perl's qw(...) and Ruby's %w[...] are. I wonder if there might be interest in some hypothetical w-string in Python, such that

w'hello world' == ["hello", "world"]

Improving Python's SimpleNamespace

Posted May 2, 2020 8:47 UTC (Sat) by smurf (subscriber, #17840) [Link] (1 responses)

> w'hello world' == ["hello", "world"]

One more character and it works today.

w/'hello world'

Writing the three-line singleton object 'w', with an appropriate dunder method, is left as an exercise to the reader.

Improving Python's SimpleNamespace

Posted May 2, 2020 10:30 UTC (Sat) by dtlin (subscriber, #36537) [Link]

Yeah, that would be simple, but precedence doesn't work out entirely in our favor:

w/'hello world'[0]

would result in "h" instead of "hello".

Improving Python's SimpleNamespace

Posted May 3, 2020 14:35 UTC (Sun) by kleptog (subscriber, #1183) [Link] (1 responses)

When dealing with complex data structures from a database or client it's useful to have a kind of "deep get" like you have, but one that gracefully handles missing entries well. Otherwise you end up with horrors like:
a.get('foo', {}).get('bar', {}).get('baz', None)
Ideally you'd like something that also handled arrays, but Python doesn't have an easy way to index an array with a default when you go off the end.

I've often ended up coding methods to do this, but it'd be cool if there was something standard.

Improving Python's SimpleNamespace

Posted May 7, 2020 5:45 UTC (Thu) by njs (subscriber, #40338) [Link]

This kind of stuff is exactly what the 'glom' package (linked in the article) is all about.

Improving Python's SimpleNamespace

Posted May 2, 2020 8:03 UTC (Sat) by PhilippWendler (subscriber, #126612) [Link] (1 responses)

Especially in complex cases JSONPath is a nice standard for this, it would allow you to write 'clothing.mens.shoes.extra_wide.quantity' here but also supports arrays etc. (like if shoes where an array and you need to find the element in it that has the extra_wide property set to true, and then retrieve quantity from it). I have not yet used it from a Python project, but it seems there are libraries implementing.

Improving Python's SimpleNamespace

Posted May 3, 2020 11:24 UTC (Sun) by mathstuf (subscriber, #69389) [Link]

I've always ended up using the JSON Pointer standard for stuff like this. Are they basically the same, with Pointer preferring `/` rather than `.`. But it seems there are quite a few existing standards for this. `-` truly would be an xkcd#927 instance :) .


Copyright © 2025, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds