News for hackers. Stuff that matters.
Re:The Next Step for Generics by throwaway894345 on Tuesday June 16, 2020 @11:03PM (#23547267)
In Python, it’s entirely idiomatic to take different types of input and do different things. Look at the pandas dataframe constructor or just about anything in the datascience ecosystem (e.g., matplotlib). Look at the open() builtin—the value of the second string argument changes the return value type. Things aren’t much better in JS land where a function might take an arg or a list or a config object, etc. We see dozens of type errors in production every day.
Re:The Next Step for Generics by waheoo on Tuesday June 16, 2020 @11:23PM (#23547388)
For what its worth, the datascience ecosystem is probably the worst place to get general idioms from. They tend to err towards their own domain language and build stuff for people who arent programmers. i.e. for caller flexibility instead of maintainability.

Besides that, i only said it was a code smell, i dont debate that its useful sometimes. Just that its a signal to be careful, check you really need itor there is t some other constraint you can break.

My only advice is that narrowing your parameter types at the earliest opportunity is a good practice and results in much easier to understand code.

Re:The Next Step for Generics by nyanpasu64 on Wednesday June 17, 2020 @05:36AM (#23549530)
I kinda wish Python took the Rust approach of having multiple factory static-methods, rather than one constructor that does different things based on what arguments you pass in.
Re:The Next Step for Generics by duckerude on Wednesday June 17, 2020 @06:34AM (#23549863)
It does that sometimes, e.g. the classmethods in https://docs.python.org/3/library/datetime.html .

But perhaps not enough.

Re:The Next Step for Generics by throwaway894345 on Wednesday June 17, 2020 @11:19AM (#23552473)
Yeah, it seems not very idiomatic. I regularly see "senior engineers" doing I/O, throwing exceptions, etc in constructors. I staunchly believe a constructor should take exactly one parameter per member variable and set the member variable. For conveniences, make static methods that invoke that constructor. This will make your code far more understandable and testable (you can initialize your object in any state without having to jump through hoops). This is language agnostic advice, but some language communities adhere to it better than others. Python is not very good about this.
Re:The Next Step for Generics by duckerude on Wednesday June 17, 2020 @01:13PM (#23553905)
I wonder if dataclasses might change this. They provide an __init__ that does what you describe, and though you can supply your own __init__ instead, classmethods seem the easier way to add custom initialization logic.
Re:The Next Step for Generics by throwaway894345 on Wednesday June 17, 2020 @03:07PM (#23555411)
Yeah, it would be a very good thing for the Python community if dataclasses became idiomatic and vanilla classes came to be regarded as a code smell. Basically what every language should have is the concept of a "struct" or a "struct pointer". Constructors imply that there is one right way to construct an object which is rarely true except in the one-param-per-member-field sense.

"Convenience constructors" (i.e., static methods for creating instances from a set of parameters) are fine, but should often not be in the same module (or perhaps even the same package) as the class anyway. For example, if you have a Book class and it has a convenience constructor for creating a book from a database connection string and a book ID, this is probably reasonable for certain applications, but if it's likely that others would want to use your book class in non-database applications, then it would be a travesty to make the non-database application take a dependency on sqlalchemy, a database driver, etc (especially since database drivers tend to be C-extensions which may or may not be difficult to install on various target platforms).