Live data from Hacker News

Advanced Python Features

blog.edward-li.com

31–40 of 183 posts

Re: Advanced Python Features

#31

This sounds fun if you have 10x programmers or at least IQ > 140 programmers in charge. Last place I worked, I was told never use "smart" tricks if you can do the same thing in a simpler way. For-else and f-strings and := sound like harmless enough (though the last one is controversial); "with" is useful for resources that need to be deallocated but "yield"? Really? "more readable" when you slap a decorator on the th…

I strongly agree. The walrus operator ... argh.

When I code, I try to make everything I write not clever. I am not saving a byte here and there because I am not typing in a program from a magazine in the 1980s (I was there, I am not going back). No code golf. I did my time on the Timex-Sinclair with its miserable two kilobytes of memory and reserved keywords as special-function strokes at a character each.

Each line should do one thing, in general, and it ought to be obvious. Cleverness is held in reserve for when it is truly needed, namely data structures and algorithms.

One of my accomplishments which seems to have mattered only to me is when my apartment-finding/renting system, written entirely in Perl, was transferred into the hands of students, new programming students. Perl is famously "write-once, read-never" and seems to have a culture favoring code golf and executable line noise. Still, the students got back to me and told me how easily-ported everything was, because I had done just one thing per line, avoided $_ and other such shortcuts, and other practices. They were very happy to take it over because I had avoided being cryptic and terse.

Re: Advanced Python Features

#32
post #10

This is all fun and games unless you have to debug someone elses code and they use a new feature that you didnt know about. Speaking for myself, I would be glad if there were a python_light version of the interpreter that has a simple syntax only like the early 3.x versions. just my 2 ct

> This is all fun and games unless you have to debug someone elses code and they use a new feature that you didnt know about.

What’s wrong about learning things by looking at code from more experienced people?

Re: Advanced Python Features

#33
post #17

Working in the ML field, I can't hate Python. But the type system (pre-3.12, of course) cost me a lot of nerves. Hoping for a better post-3.12 experience once all libraries are usable in 3.12+. After that experience, I’ve come to truly appreciate TypeScript’s type system. Never thought I’d say that.

One of the most frustrating bugs I had encountered was when I was using memory mapped CSC format sparse arrays.

I needed the array indices to be int64 and specified them as such during initialization.

Downstreams, however, it would look at the actual index values and dynamically cast them to int32 if it judged there would be no loss in precision. This would completely screw up the roundtrip through a module implemented in C.

Being an intermittent bug it was quite a hell.

Re: Advanced Python Features

#34

This sounds fun if you have 10x programmers or at least IQ > 140 programmers in charge. Last place I worked, I was told never use "smart" tricks if you can do the same thing in a simpler way. For-else and f-strings and := sound like harmless enough (though the last one is controversial); "with" is useful for resources that need to be deallocated but "yield"? Really? "more readable" when you slap a decorator on the th…

I don't fully disagree, but the yield context manager approach is very common when writing test fixtures, you do:

  # setup  
  yield resource. 
  # teardown
Not that it makes it any less magical, but at least it's a consistent python pattern

Re: Advanced Python Features

#36
post #24

This sounds fun if you have 10x programmers or at least IQ > 140 programmers in charge. Last place I worked, I was told never use "smart" tricks if you can do the same thing in a simpler way. For-else and f-strings and := sound like harmless enough (though the last one is controversial); "with" is useful for resources that need to be deallocated but "yield"? Really? "more readable" when you slap a decorator on the th…

I don’t really see "smart tricks" here, just features of the language that you may not be aware of. I use most of them in my daily work without thinking about it: `@overload` and other typing features are useful to document the code, prevent mistakes, and help IDEs generate more helpful suggestions; keyword-only arguments force users to pass options as keywords, so you avoid calls like `foo(x, z, z, true, true, false…

overload is very useful, but I find some people mistakenly think it actually modifies the runtime function signature to do multiple dispatch, so I do try to avoid it in favour of simpler functions whenever possible

too many overloads can be a code smell IMHO, it's ok when you are implementing a very common pattern and want proper types (decorators come to mind, so that both @decorator and @decorator() work, where the decorator might also have optional args) but I think in cases like the example in the article it should almost always be two separate functions

Re: Advanced Python Features

#38
Good list, its one of these things you either never heard of, or used for years and think everyone knew that. I'll add a few:

* did you know __init__.py is optional nowadays?

* you can do relative imports with things like "from ..other import foo"

* since 3.13 there is a @deprecated decorator that does what you think it does

* the new generics syntax also works on methods/functions: "def method[T](...)" very cool

* you can type kwargs with typeddicts and unpack: "def fn(*kwargs: Unpack[MyKwargs])"

* dataclasses (and pydantic) support immutable objects with: "class MyModel(BaseModel, frozen=True)" or "@dataclass(frozen=True)"

* class attributes on dataclasses, etc. can be defined with "MY_STATIC: ClassVar[int] = 42" this also supports abstract base classes (ABC)

* TypeVar supports binding to enforce subtypes: "TypeVar['T', bound=X]", and also a default since 3.13: "TypeVar['T', bound=X, default=int]"

* @overload is especially useful for get() methods to express that the return can't be none if the default isn't None

* instead of Union[a, b] or Optional[a] you can write "a | b" or "a | None" nowadays

* with match you can use assert_never() to ensure exhaustive matching in a "case _:" block

* typing has reveal_type() which lets mypy print the type it thinks something is

* typing's "Self" allows you to more properly annotate class method return types

* the time package has functions for monotonic clocks and others not just time()

anyone know more things?

Re: Advanced Python Features

#39
post #27

Earlier quoted context omitted.

0 can be inferred as a float too, so doesn’t it make sense to type numbers?

Try: def f(i=0) -> None: reveal_type(i) The inferred type is not `float` nor `int`, but `Any`. Mypy will happily let you call `f("some string")`.

That's a mypy issue.

Pyright correctly deduces the type as int.

In any case it's a bad example as function signatures should always be typed.

Re: Advanced Python Features

#40
post #18
post #17

Working in the ML field, I can't hate Python. But the type system (pre-3.12, of course) cost me a lot of nerves. Hoping for a better post-3.12 experience once all libraries are usable in 3.12+. After that experience, I’ve come to truly appreciate TypeScript’s type system. Never thought I’d say that.

Same experience here, Python’s typing experience is awful compared to TypeScript, even post-3.12. Mypy’s type inference is so dumb you have to write arguments like `i: int = 0`; `TypedDict`s seems promisable at first and then end up as a nightmare where you have to `cast` everything. I miss TypeScript’s `unknown` as well.

You really should check out pyright/pylance/basedpyright. Just an all around better type checker. Even has the "unknown" from typescript (kinda).
Post reply on HN