Live data from Hacker News

What's New in Python 3.12

docs.python.org

51–60 of 120 posts

Re: What's New in Python 3.12

#51
post #43

Earlier quoted context omitted.

While not as short as a proper operator .get("key", {}) does work.

Of course this only works at one level and not arbitrarily deeply, but you still need to check for None with this code; it may actually be better to write `x.get("key") or {}` so that you always get an empty dict. I write 'may' because the difference between None and an empty dict may be very subtle and rarely does the API specify with enough precision what are supposed to be the semantics of each case.

> Of course this only works at one level and not arbitrarily deeply

It does though, you can chain as many of these as you want:

    some_dict.get("level_1_key", {}).get("level_2_key", {}).get("level_3_key", {})...
edit:

>> but you still need to check for None with this code

> Not sure what you mean here. You only have to check for None if you use `.get("key")` and don't provide a fallback value.

GP was talking about `{"foo": None}` and trying to drill deeper, which I misunderstood. Still, a simple try/except allows you to short-circuit the deeply nested access.

Re: What's New in Python 3.12

#52

PEP 695 is great. I've been using mypy every day at work in last couple years or so with very strict parameters (no any type etc) and I have experience writing real life programs with Rust, Agda, and some Haskell before, so I'm familiar with strict type systems. I'm sure many will disagree with me but these are my very honest opinions as a professional who uses Python types every day: * Some types are better than no…

I've been steadily finding the love for F# for sort-of-similar-but-not-quite-the-same reasons. I like Python. It's still my go-to language for most things. But I definitely feel a tail off in utility as code base size increases, and I find myself asking mentally "but what type is that thing?".

F# is sort of the opposite of Python. It's strongly, statically and soundly typed, based on Hindley-Milner. It has very good type inference, meaning that explicit type annotations are usually not required. But it's still type checked, and compilation will fail if there are type errors. So F# gives you type soundness without requiring type annotations (in most cases); Python now supports type annotations but doesn't (yet) give type soundness guarantees.

Of course, F# doesn't have the Python ecosystem, and that's a major issue. Whilst it sits on the .Net platform, it's very much Sunday League to C#'s premier division. Whilst most all .Net libs can be used in F# thanks the .Net CLR, very little is idiomatic: F# is a functional language, C# is object-oriented at heart.

I think my fantasy platform would be some child of F#-the-language and Python-the-ecosystem. Maybe Python's incremental support for typing will get me there someday.

Re: What's New in Python 3.12

#53

I suspect people will use these comments to share their wishlist of Python features, so let me add that I really wish Python had a safe navigation operator, for when you are dealing with nested objects that could be None. I have been trying to parse a lot of XML and JSON in Python lately and a feature like that could really help reduce boilerplate checks. https://en.wikipedia.org/wiki/Safe_navigation_operator

I believe PEP505 should cover what you're asking, but from what I can tell it seems stalled out.

https://peps.python.org/pep-0505/

Re: What's New in Python 3.12

#54
post #51
post #43

Earlier quoted context omitted.

Of course this only works at one level and not arbitrarily deeply, but you still need to check for None with this code; it may actually be better to write `x.get("key") or {}` so that you always get an empty dict. I write 'may' because the difference between None and an empty dict may be very subtle and rarely does the API specify with enough precision what are supposed to be the semantics of each case.

> Of course this only works at one level and not arbitrarily deeply It does though, you can chain as many of these as you want: some_dict.get("level_1_key", {}).get("level_2_key", {}).get("level_3_key", {})... edit: >> but you still need to check for None with this code > Not sure what you mean here. You only have to check for None if you use `.get("key")` and don't provide a fallback value. GP was talking about `{"f…

The issue is if the dictionary has a key defined and the value is None. Your get expression will return None, causing your next access to raise an error.

Re: What's New in Python 3.12

#55
post #51
post #43

Earlier quoted context omitted.

Of course this only works at one level and not arbitrarily deeply, but you still need to check for None with this code; it may actually be better to write `x.get("key") or {}` so that you always get an empty dict. I write 'may' because the difference between None and an empty dict may be very subtle and rarely does the API specify with enough precision what are supposed to be the semantics of each case.

> Of course this only works at one level and not arbitrarily deeply It does though, you can chain as many of these as you want: some_dict.get("level_1_key", {}).get("level_2_key", {}).get("level_3_key", {})... edit: >> but you still need to check for None with this code > Not sure what you mean here. You only have to check for None if you use `.get("key")` and don't provide a fallback value. GP was talking about `{"f…

    >>> foo = {"foo": None}
    >>> print(foo.get('foo', {}).get('bar'))
    Traceback (most recent call last):
      File "", line 1, in 
    AttributeError: 'NoneType' object has no attribute 'get'
    >>> print((foo.get('foo') or {}).get('bar'))
    None

Re: What's New in Python 3.12

#56

I suspect people will use these comments to share their wishlist of Python features, so let me add that I really wish Python had a safe navigation operator, for when you are dealing with nested objects that could be None. I have been trying to parse a lot of XML and JSON in Python lately and a feature like that could really help reduce boilerplate checks. https://en.wikipedia.org/wiki/Safe_navigation_operator

    def safe_navigation(obj, path: List[str], default=None):
        try:
            for key in path:
                obj = obj[key]
            return obj
        except KeyError:
            return default 
Yeah. I thought it would just be a try-except, but that turned out pretty ugly.

But really, how do you know if your path is missing or the object at the end of the path is None, without using exceptions for communicating this?

Re: What's New in Python 3.12

#57
post #51

Earlier quoted context omitted.

> Of course this only works at one level and not arbitrarily deeply It does though, you can chain as many of these as you want: some_dict.get("level_1_key", {}).get("level_2_key", {}).get("level_3_key", {})... edit: >> but you still need to check for None with this code > Not sure what you mean here. You only have to check for None if you use `.get("key")` and don't provide a fallback value. GP was talking about `{"f…

The issue is if the dictionary has a key defined and the value is None. Your get expression will return None, causing your next access to raise an error.

Ah, I see. Still, I'd just catch that exception and move on because it's obvious you won't have anything more deeply nested anyway. Blowing up on `None` is an easy short-circuit.

Re: What's New in Python 3.12

#58
post #43

Earlier quoted context omitted.

While not as short as a proper operator .get("key", {}) does work.

Of course this only works at one level and not arbitrarily deeply, but you still need to check for None with this code; it may actually be better to write `x.get("key") or {}` so that you always get an empty dict. I write 'may' because the difference between None and an empty dict may be very subtle and rarely does the API specify with enough precision what are supposed to be the semantics of each case.

> x.get("key") or {}

This has the side effect of replacing falsy values like False or 0 with an empty dictionary instead of giving you the actual value. For the exact intended behaviour, you do need to explicitly check for None instead of using a short circuit trick with or.

Re: What's New in Python 3.12

#59
post #55
post #51

Earlier quoted context omitted.

> Of course this only works at one level and not arbitrarily deeply It does though, you can chain as many of these as you want: some_dict.get("level_1_key", {}).get("level_2_key", {}).get("level_3_key", {})... edit: >> but you still need to check for None with this code > Not sure what you mean here. You only have to check for None if you use `.get("key")` and don't provide a fallback value. GP was talking about `{"f…

>>> foo = {"foo": None} >>> print(foo.get('foo', {}).get('bar')) Traceback (most recent call last): File " ", line 1, in AttributeError: 'NoneType' object has no attribute 'get' >>> print((foo.get('foo') or {}).get('bar')) None

Right, see my other comment:

> Blowing up on `None` is an easy short-circuit.

The thing being discussed is attempting to access deeply nested values, so short-circuiting here is a win-win. I.e., you wouldn't want to unnecessarily traverse tons of empty dictionaries using the `.get() or {}` trick.

Re: What's New in Python 3.12

#60

I suspect people will use these comments to share their wishlist of Python features, so let me add that I really wish Python had a safe navigation operator, for when you are dealing with nested objects that could be None. I have been trying to parse a lot of XML and JSON in Python lately and a feature like that could really help reduce boilerplate checks. https://en.wikipedia.org/wiki/Safe_navigation_operator

I use Pydantic for this for JSON.
Post reply on HN