What Is The Use Of @staticmethod ?
Posted by One-Type-2842@reddit | Python | View on Reddit | 31 comments
I run examples to understand @staticmethod, but I end up found no more usefulness of this decorator
```
# In a class Pizza:
@staticmethod
def get_size_in_inches(size):
"""Returns the diameter in inches for common pizza sizes."""
size_map = {
"small": 8,
"large": 16,
}
return size_map.get(size, "Unknown size")
```
```
# In a class Pizza:
def get_size_in_inches(self, size):
"""Returns the diameter in inches for common pizza sizes."""
size_map = {
"small": 8,
"large": 16,
}
return size_map.get(size, "Unknown size")
```
Both of the above methods are similar to access.
Someone Explain me what is the use of @staticmethod then?
Is it a type hint of editors or related to compiler?
Python-ModTeam@reddit
Hi there, from the /r/Python mods.
We have removed this post as it is not suited to the /r/Python subreddit proper, however it should be very appropriate for our sister subreddit /r/LearnPython or for the r/Python discord: https://discord.gg/python.
The reason for the removal is that /r/Python is dedicated to discussion of Python news, projects, uses and debates. It is not designed to act as Q&A or FAQ board. The regular community is not a fan of "how do I..." questions, so you will not get the best responses over here.
On /r/LearnPython the community and the r/Python discord are actively expecting questions and are looking to help. You can expect far more understanding, encouraging and insightful responses over there. No matter what level of question you have, if you are looking for help with Python, you should get good answers. Make sure to check out the rules for both places.
Warm regards, and best of luck with your Pythoneering!
Henry_old@reddit
staticmethods are just for namespacing. if you dont need self or cls then make it static. keeps the class tidy. i use it for small math helpers in my bots so they dont clutter the global namespace. its more about code organization than performance honestly
Gnaxe@reddit
No, staticmethods are not just for namespacing, where are you hearing that? They're for polymorphism just like normal methods, but they don't require the instance.
Henry_old@reddit
staticmethods dont see class or self so polymorph is useless there its just a function in class wrapper for clean code skip academic theory its just a helper for bots
Gnaxe@reddit
You're still confused. Need a concrete example?
Polymorphism with static methods. The
@staticmethodsdon't need theselfto do it, because it's the dispatch part that matters.ProsodySpeaks@reddit
I'm totally self taught, and understand the practical reasons for this setup, but just think if it in terms of inheritance and overrides. In fact for completeness id decorate dog.think() with @override.
Can you explain a little what polymorphism is in this context? Is it just a superset of inheritance? Like accepting multiple types in one place?
Gnaxe@reddit
Polymorphism (literally "many-form-process") is about having operations that work (but maybe differently) on more than one type, by allowing values (or variables) to count as more than one type.
For example,
list()andset()are distinct types, but you can pull values from either of them using for loop becauseiter()works on both of them, but it works completely differently inside.set()doesn't even guarantee order, just that you'll get each value inside once.In my example,
Dogis a subclass ofAnimal, meaning allDoginstances also count as having theAnimaltype, and they understand the same messages/method calls that anyAnimalwould, even though the behavior is different. If you know you have a list of animals, you can safely call.speak()on them, even if some of them might also beDogs.Internally, the
.speak()method is also using polymorphism.Doginherited exactly the same implementation used byAnimal, but we don't know ifselfis aDogtype or not here. That's OK, we do know it's anAnimaland it only needs to understand the.think()method to work, whichAnimalalso provided. However,Dogoverrode this one, which is not something you could do with a top-level helper function, which was my main point.@overrideis only a sign to a static type checker to ensure that the superclass has the same method name. It has no run time effect and is not required.Some languages do method dispatch statically, but Python isn't one of them. The lookup happens dynamically. When
.speak()callsself.think(), it does a lookup to dispatch to the right implementation of.think(). In Python, this starts by looking in the instance__dict__(unless you're using slots), and then in each superclass in the method resolution order. (You can usesuper()to skip ahead in this order, but we're not doing that here.)ProsodySpeaks@reddit
Nice one. So if my func accepts
MyType | iterable[MyType]then it's polymorphic?I made a shipping client that connects our crm to various shipping clients. So I have a base
Shipable(BaseModel, ABC)pydantic class with abstractshipment()method, and then children likeSale(Shipable)andhire(Shipable)which model database tables and implement shipment() to produce an agnostic representation of a shipment from the appropriate fields in their respective DB tables.Then I have various subclasses of
ShippingProviderwhich take the agnostic shipment and do whatever they need to do to book shipping.Is this polymorphism?
Gnaxe@reddit
If you're calling a
shipment()method in code that doesn't know if it's talking to a Sale or a Hire-type object, but can reasonably expect that it's at least a Shipable type regardless, and which differ in their implementations ofshipment(), then yes, that's polymorphic.I can't say exactly how good/bad your design is from that much, but I think ORMs in general are terrible. I think static typing is probably doing more harm than good in Python. I think abstract base classes are usually less bad than concrete ones. I think classes are way overused in Python, and I think OOP is a bad fit for our current multicore architectures (and concurrency remains one of Python's biggest weaknesses). FP is better at handling multiple cores because it controls and minimizes state better, rather than just hiding it behind interfaces like you do in OOP. Python does have class statements built in, but you mostly don't have to write them. The two times it's required are when you have to subclass to use library code (ORMs, for example, or standard-library unit tests) or when you need to write a dunder method. You might also need them when maintaining legacy code, for reasons similar to library code. Sometimes a rewrite isn't worth it.
ProsodySpeaks@reddit
I've been pretty interested in fp recently. Yes my shipper takes the abstract base type and doesn't care about the concrete type. Would replacing this with eg a load of functions with overload decorators, one for each type of Shipable? Or what is a good approach to handling multiple types in a fairly dry way with bare functions?
Gnaxe@reddit
Python also has
@functools.singledispatchin the standard library for type dispatch. And Python is duck-typed, so anything that respects your ad-hoc protocols may be valid, regardless of where it fits on the class hierarchy. Functions are first-class objects in Python, so you could pass around a function directly, instead of an object with a method. Functions can also be partially applied (e.g., withfunctools.partial()), similar to theselfbinding for methods.In a more functional, but still dynamically typed language (like Clojure), we wouldn't use an ORM at all. We wouldn't have a type for each table in the database and an instance thereof for each row. We'd just treat data as data. You could think of a table as a list of dicts. (A vector of maps in Clojure.) And write your own SQL to access it. FP prefers pure functions, so you'd only talk to the database near the boundary (i.e., in or near an entry point, like main, or whatever your router calls). Python can be written in this style, and it scales a lot better than OOP with static typing.
For your shipping example, you might have a common
shipment()function that operates on a dict and expects certain keys it needs to be present. Tables (or queries, rather) that don't already have the right form, would need a function to convert them, just like how your ORM version has different.shipment()methods and maybe a common part you'd access viasuper().Not that different on its face, but your code is more reusable because you let data be data and write more generic functions to operate on any data that conforms to a minimal spec (like having certain keys), rather than hiding each special case behind its own inadequate bespoke method language by writing a class.
One-Type-2842@reddit (OP)
Explain me @staticmethod relation to namespaces.
Henry_old@reddit
namespace means grouping funcs under class name instead of global mess keeps code tidy and logical so you call class.func instead of having random funcs everywhere
ryanfelix123@reddit
The main use is namespace management. If a utility function is only relevant to a specific class, putting it inside that class as a static method keeps the global namespace clean. It also helps with code discoverability. If I’m using DateHelper class, I’d expect to find is_valid_date() inside it, even if it doesn't need to modify a specific date instance.
AlexMTBDude@reddit
FYI: Python does not have a compiler, it's an interpreted language.
melesigenes@reddit
What are you talking about? Every language, unless you’re writing in machine code somehow, has a compiler
Gnaxe@reddit
Maybe any language could in principle have a compiler, but that's not the same as saying a compiler actually exists. Interpreters are not automatically compilers. A compiler has to translate one formal language to another to count (not necessarily machine code). An interpreter only has to execute a list of instructions. It doesn't have to rewrite them first. But Python has multiple implementations, including compilers.
melesigenes@reddit
What do you mean maybe any language could have a compiler? You’ve written the dumbest most pedantic straw man tautological drivel I’ve seen on this forum. None of what you wrote refutes what I wrote. Name me one language that doesn’t have a step that “translates one formal language to another (not necessarily machine code)”.
max96t@reddit
I get what you mean, since it's not compiled to machine code. However, Python has a compiler and is (usually) compiled to bytecode. The interpreter then interprets the bytecode.
But I don't know what OP meant when they mentioned the compiler
ToddBradley@reddit
And therefore all the .pyc file you see are figments of your imagination
Gnaxe@reddit
False. So much misinformation on this sub. Python is a compiled language. It has a compiler.
compile()is literally a builtin, and it can translate strings of Python code into whatever your Python implementation uses. In CPython, that's CPython bytecodes. That's basically the same idea as the Java compiler. You can also explicitly pre-compile a file from the command line withpython -m compileall. Python then doesn't require the source to run it, just the compiled files.End0rphinJunkie@reddit
Its mostly just about logical grouping so you don't pollute the global namespace with random helper functions. When writing heavy deployment automations, keeping pure logic scoped to a class without needing to instanciate an object keeps the codebase super clean.
shiralikoushik2@reddit
Static methods are used to group those methods which relates or functionally belongs to class but doesn't use any instance variable or class variable! It gives you clarity that those methods relates to class but doesn't use any of class / instance variable!
VisibleSmell3327@reddit
Don't need an instance of the class to call it.
Gnaxe@reddit
Right, you can call it directly from the class object instead. But they can use an instance for polymorphism. It just isn't passed in as an argument.
case_O_The_Mondays@reddit
I’ve used static methods to create new class instances from alternate methods, without blowing out my init method’s parameters and logic.
Gnaxe@reddit
A normal method takes
selfas its first argument. A@classmethodtakesclsinstead (the class, not the instance). A@staticmethodtakes neither, so it works more like a toplevel function. But unlike with a toplevel function, you can still override a@staticmethodin a subclass. This is the polymorphism that makes it a method rather than just a function. It's not "just for namespacing."mustbeset@reddit
A staticmethod has no "self" parameter. You can access that function without initialization but have no access to any class instance data (because self is missing).
It's semantically more clear and maybe (I am not a Python performance expert) a bit faster
ProsodySpeaks@reddit
A staticmethod is one which doesn't take a 'self' argument.
This means you can run it any time any place without first instantiating the class into an object, but that it doesn't have access to any instance-variables.
Imagine a class that takes lots of input data to build, and then a method that is related to the class but doesn't need any of the data stored in objects -this is a candidate for staticmethod
hikingsticks@reddit
Engagement farming bot
Sensitive_One_425@reddit
You can ask these basic questions to literally any AI and get the answer you need much faster than spamming this subreddit.