3 ms·
it's not all bad but doing generic types is annoying because you have to do from typing import TypeVar T = TypeVar('T') in every module where you want to
by uryga 8y ago
it's not all bad but doing generic types is annoying because you have to do
from typing import TypeVar
T = TypeVar('T')
in every module where you want to parametrize a type.
(not sure how that works with 3.6+'s unevaluated annotations. that's what my linter thinks)
also callable types are really ugly... this:
Callable[[Foo, Bar], Baz]
vs something like `(Foo, Bar) -> Baz` is just yuck
putting constraints on a type is pretty ugly too iirc, i think it looks something like
F = TypeVar(bound=Foo)
def bar(a: F, b: F) -> F: ...
hacking type annotations into the language's existing syntax is hard :(
- joshuamorton 8y agoI actually find this a feature. If you have a function that takes `(Foo, Bar) -> Baz`, What you really have is a function that takes in a FoobarBazifier. So name your function-interface: FoobarBazifier = Callable[[Foo, Bar], Baz] def my_func(cb: FoobarBazifier) -> Baz: ... This is pythonic, in the same way that preferring named functions over lambdas (and therefore not having a single character lambda syntax) is pythonic. Its controversial and people dislike it, but it is nice. It also has the side effect of letting you Subclass the interface if you want to (via NewType), so that if you have multiple functions that match the same signature but fulfill different interfaces, you can name the interfaces differently and use them in different places. Java mostly enforces this because you have to define an explicit interface and class for your callbacks (or you did until java 8), this is essentially the same thing, but with 1 line of boilerplate instead of 25 across 3 files.