When and how are static methods supposed to be used in python?
Glib answer: Not very often.
An even, but not entirely useless answer: when they make your code more readable.
First, take a workaround in the docs :
Static methods in Python are similar to those that exist in Java or C ++. Also see classmethod() for an option that is useful for creating alternative class constructors.
So, when you need a static method in C ++, you need a static method in Python, right?
Oh no.
There are no functions in Java, just methods, so you create pseudo-classes that are just static method associations. The way to do the same in Python is to simply use free functions.
This is pretty obvious. However, it is a good Java style to look as difficult as possible for the corresponding class to insert a function into it, so you can avoid writing these pseudo-classes while doing the same thing, this is a bad Python style - use free functions again - and it is much less obvious.
C ++ does not have the same restriction as Java, but many C ++ styles are pretty similar. (On the other hand, if you are a Modern C ++ programmer who has learned the words “free functions that are part of the class interface”, your instincts for “where static methods are useful” are probably pretty good for Python.)
But if you come to this from the first principles, and not from another language, there is an easier way to look at things:
A @staticmethod is basically just a global function. If you have a function foo_module.bar() that would be more readable for some reason, if it were written as foo_module.BazClass.bar() , make it @staticmethod . If not, do not do this. That is really all that is needed. The only problem is creating your instincts for what is more readable for the idiomatic Python programmer.
And of course, use @classmethod when you need access to the class, but not instance constructors-alternators - this is the paradigm for this, as the docs imply. Although you can often model @classmethod with @staticmethod , just explicitly referring to the class (especially if you don't have a large subclass), you shouldn't.
Finally, going to your specific question:
If the only reason customers should ever look up data by identifier is to create an Entity that sounds like an implementation detail that you shouldn't disclose, and also makes client code more complex. Just use the constructor. If you do not want to change your __init__ (and you are right that there are good reasons for which you do not want to), use @classmethod as an alternative constructor: Entity.from_id(id_number, db_connection) .
On the other hand, if this search is something that is inherently useful for clients in other cases that have nothing to do with the Entity construct, it looks like it has nothing to do with the Entity class (or at least no more than anything else in one module). So just make it a free function.