Earlier quoted context omitted.
If you have enough arguments that the signature becomes obscure to read you need a dataclass to pass into the function instead. I would rather: @dataclass(frozen=True, slots=True) class VarThings: n: int ... def variable(a: VarThings): ... Than a million args
I usually start with a namedtuple unless I need the additional features provided by a dataclass.
Python Type Hints – *args and **kwargs (2021)
71–80 of 158 posts
Re: Python Type Hints – *args and **kwargs (2021)
#72Earlier quoted context omitted.
When you slice a list, you get a list. When you see there is nothing inside the returning list, you know that means end of list, contains zero element. Slicing and indexing return object at different level.
Slicing a list, when the first index is invalid for that list, could easily throw an exception instead.
Re: Python Type Hints – *args and **kwargs (2021)
#73For typing **kwargs there are TypedDicts https://peps.python.org/pep-0692/ If your function just wraps another you can use the same type hints as the other function with functools.wraps https://docs.python.org/3/library/functools.html#functools.w...
Not ideal but not too bad either.
Re: Python Type Hints – *args and **kwargs (2021)
#74Earlier quoted context omitted.
You should use `Iterable`
I'm not sure print(firstname, lastname) for example is more readable than print((firstname, lastname)) especially since I would then have to write print((surname,)) to just print a single string. Variadic functions are rather classic, I think Go, Rust, C and JavaScript also have them.
Re: Python Type Hints – *args and **kwargs (2021)
#75Earlier quoted context omitted.
What do you do when inheriting from a base class with a defined __init__ ?
For everybody reading this and scratching their head why this is relevant: Python subclassing is strange. Essentially super().__init__() will resolve to a statically unknowable class at run-time because super() refers to the next class in the MRO. Knowing what class you will call is essentially unknowable as soon as you accept that either your provider class hierarchy may change or you have consumers you do not contr…
Instead, I've come to prefer a style I took from Julia: every class is either (a) abstract, or (b) concrete and final.
Abstract classes exist to declare interfaces.
__init__ methods only exist on concrete classes. After that it should be thought of as unsubclassable, and concerns about inheritance and diamond dependencies etc just don't exist.
(If you do need to extend some functionality: prefer composition over inheritance.)
Re: Python Type Hints – *args and **kwargs (2021)
#76Is it just me or are Python type hints like..goofy?
Re: Python Type Hints – *args and **kwargs (2021)
#77The ability of **kwargs to leave behind no proper documentation and silently swallow any invalid arguments has made us remove them entirely from our codebase. They're almost entirely redundant when you have dataclasses.
Re: Python Type Hints – *args and **kwargs (2021)
#78Is it just me or are Python type hints like..goofy?
A language being statically typed or dynamically typed is a design decision with implications for what the language can do. There are benefits to each method of programming.
Trying to strap type checking on to Python is born out of some misplaced belief that static type is just better. Using Python as a dynamically typed language allows you for certain programming patterns that cannot be done in a statically typed language. There are some great examples in SICP of Scheme programs that could not exist (at least with as much elegance) in a typed language. Dynamic typing allows a language to do things that you can't do (as easily/elegantly) in a statically typed language.
Some may argue that these type of programming patterns are bad for production systems. For most of these arguments I strongly agree. But that means for those systems Python is probably a poor choice. I also think metaprogramming is very powerful, but also a real potential footgun. It would be ridiculous to attempt to strip metaprogramming from Ruby to make it "better", just use a language that depends less on metaprogramming if you don't like it.
This is extra frustrating because in the last decade we've seen the options for well designed, statically typed languages explode. It's no longer Python vs Java/C++. TypeScript and Go exist, have great support and are well suited for most of the domains that Python is. Want types? Use those languages.
Re: Python Type Hints – *args and **kwargs (2021)
#79Earlier quoted context omitted.
What about decorators, or wrappers around third-party code whose contracts change frequently (or even second party code when interacting with functions provided by teams that don't follow explicit argument typing guidelines, if you have that sort of culture)?
Usually the solutions range from a culture of “just don’t” to tests/mypy that have become increasingly stricter over the years, every time we’ve come a step further up the ladder. But I admit, it has taken quite some bridging to get there. Moving to static Python in most places has dramatically improved the code and language.
Re: Python Type Hints – *args and **kwargs (2021)
#80Earlier quoted context omitted.
You should use `Iterable`
I'm not sure print(firstname, lastname) for example is more readable than print((firstname, lastname)) especially since I would then have to write print((surname,)) to just print a single string. Variadic functions are rather classic, I think Go, Rust, C and JavaScript also have them.