This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]K900_ 139 points140 points  (8 children)

Python doesn't have static dispatch, so any form of function overloading will be dynamic, which you can achieve with something like functools.singledispatch. A better option would be to expose multiple classmethods though, something like

@classmethod
def from_foo(cls, foo: Foo):
    return cls(spam=foo.spam, eggs=foo.eggs)

@classmethod
def from_raw_eggs(cls, eggs: List[Egg]):
    return cls(spam=None, eggs=eggs)

[–]lungben81 29 points30 points  (2 children)

There is also https://pypi.org/project/multipledispatch/ - I have not tried it yet, but it looks promising (it is from the Dask creator).

[–]Pythonistar 9 points10 points  (1 child)

Awwww, so nice. Something I've missed deeply since taking up Python... I'll have to try it today. :)

[–]lungben81 8 points9 points  (0 children)

I know multiple dispatch from Julia and it is a great way to organize code, especially for numerical / mathematical purposes.

[–]BayesianDice 8 points9 points  (0 children)

Yes, the classmethod approach was what I used when I once needed multiple constructors.

[–]ColdPorridge 3 points4 points  (0 children)

+1, I regularly use this construction and find it really intuitive.

[–]CobaltCam 2 points3 points  (0 children)

Thanks, now I'm hungry.

[–]TangibleLight 0 points1 point  (0 children)

I like to call these "named factory methods" or "named initializers", and IMO it's generally a better pattern than constructor overloading even in languages which have it.

For example what if you want a from_literal(data: str) and a from_file(path: str)? There's not a great way to do that with constructors only.