Static classes in Python
Asked Answered
P

5

33

I once read (I think on a page from Microsoft) that it's a good way to use static classes, when you don't NEED two or more instances of a class.

I'm writing a program in Python. Is it a bad style, if I use @classmethod for every method of a class?

Pitterpatter answered 30/4, 2012 at 17:46 Comment(0)
A
14

In my experience creating a class is a very good solution for a number of reasons. One is that you wind up using the class as a 'normal' class (esp. making more than just one instance) more often than you might think. It's also a reasonable style choice to stick with classes for everthing; this can make it easier for others who read/maintain your code, esp if they are very OO - they will be comfortable with classes. As noted in other replies, it's also reasonable to just use 'bare' functions for the implementation. You may wish to start with a class and make it a singleton/Borg pattern (lots of examples if you googlefor these); it gives you the flexibility to (re)use the class to meet other needs. I would recommend against the 'static class' approach as being non-conventional and non-Pythonic, which makes it harder to read and maintain.

Admonition answered 30/4, 2012 at 18:0 Comment(3)
Most of your answer, major exceptions being the second and the last sentence, is just arguable (and I tend to disagree) and beside the point. I'd say cutting all the fluff on how great classes are would improve it, what do you think?Wynnie
I both agree and disagree with this answer at the same time. So I can't decide whether to hit up or down button. Anyway I agree about the Objects making code easier to read and maintain. I disagree about using the singleton/borg pattern python-3-patterns-idioms-test.readthedocs.io/en/latest/…. Its not that its a bad pattern; however, using static methods with class variables is way easier to maintain and read in an extremely complicated code project. Yes this may not technically be correct but junior level programmers will thank you.Triliteral
a lot of the right pieces are here in this answer, but they feel loaded with the wrong implications. Notably the "classes if working with other OO programmers" is a valid point--conform with the style of a codebase, always good advice. I'm mostly bothered by the 2nd sentence that suggests using a class b/c you may be surprised how often it's reused. I'd recommend a little more planning--hopefully you know how frequently it will get reused in your architecture (but also note there are other reasons to make a class than just reuse)Hewlett
R
40

Generally, usage like this is better done by just using functions in a module, without a class at all.

Recriminate answered 30/4, 2012 at 17:48 Comment(5)
+1. Absolutely no need to create a class in Python if you're not encapsulating any data.Aquatint
I sometimes start with just functions but then realize that, because I like writing small functions, I sometimes have to pass the same parameter between 3 or 4 of them, at which point I start to want to encapsulate that parameter. I have yet to solve this conundrum. Thoughts?Rech
@Rech I'd argue that if your functions are independent but still want the parameters between them, just pass those parameters. If you find you have a lot of calls with the same collections of paramteres, maybe produce a namedtuple or something to pass around. Storing things in a class just to avoid passing them around is generally a bad idea anyway - it could result in issues.Recriminate
@Lattyware, I do not like using state as a philosophy but the real functional languages (Like F#, Clojure, Haskell) still occupy a rather small niche. Python is a multi-paradigm language, so it is often up to the programmer how to use it. The following is rather vague: "Storing things in a class just to avoid passing them around is generally a bad idea anyway - it could result in issues.". Would you elaborate on specific dangers, issues, drawbacks? Otherwise I might assume that you hold a bias for functions and against objects.Rech
@Rech I'm definitely not advocating avoiding state completely - especially in Python. What I mean is that if storing values in a class shouldn't be used where the lifespan of the value is that of the function call - literally just to avoid passing the value through child functions. The danger is that suddenly that state could be mutated externally (say the function gets run elsewhere) which could result in bugs and fragility. It also reduces the ability to reuse those functions as easily due to their reliance on this state.Recriminate
C
15

It's terrible style, unless you actually need to access the class.

A static method [...] does not translate to a Python classmethod. Oh sure, it results in more or less the same effect, but the goal of a classmethod is actually to do something that's usually not even possible [...] (like inheriting a non-default constructor). The idiomatic translation of a [...] static method is usually a module-level function, not a classmethod or staticmethod.

source

Centro answered 30/4, 2012 at 17:49 Comment(0)
A
14

In my experience creating a class is a very good solution for a number of reasons. One is that you wind up using the class as a 'normal' class (esp. making more than just one instance) more often than you might think. It's also a reasonable style choice to stick with classes for everthing; this can make it easier for others who read/maintain your code, esp if they are very OO - they will be comfortable with classes. As noted in other replies, it's also reasonable to just use 'bare' functions for the implementation. You may wish to start with a class and make it a singleton/Borg pattern (lots of examples if you googlefor these); it gives you the flexibility to (re)use the class to meet other needs. I would recommend against the 'static class' approach as being non-conventional and non-Pythonic, which makes it harder to read and maintain.

Admonition answered 30/4, 2012 at 18:0 Comment(3)
Most of your answer, major exceptions being the second and the last sentence, is just arguable (and I tend to disagree) and beside the point. I'd say cutting all the fluff on how great classes are would improve it, what do you think?Wynnie
I both agree and disagree with this answer at the same time. So I can't decide whether to hit up or down button. Anyway I agree about the Objects making code easier to read and maintain. I disagree about using the singleton/borg pattern python-3-patterns-idioms-test.readthedocs.io/en/latest/…. Its not that its a bad pattern; however, using static methods with class variables is way easier to maintain and read in an extremely complicated code project. Yes this may not technically be correct but junior level programmers will thank you.Triliteral
a lot of the right pieces are here in this answer, but they feel loaded with the wrong implications. Notably the "classes if working with other OO programmers" is a valid point--conform with the style of a codebase, always good advice. I'm mostly bothered by the 2nd sentence that suggests using a class b/c you may be surprised how often it's reused. I'd recommend a little more planning--hopefully you know how frequently it will get reused in your architecture (but also note there are other reasons to make a class than just reuse)Hewlett
U
6

There are a few approaches you might take for this. As others have mentioned, you could just use module-level functions. In this case, the module itself is the namespace that holds them together. Another option, which can be useful if you need to keep track of state, is to define a class with normal methods (taking self), and then define a single global instance of it, and copy its instance methods to the module namespace. This is the approach taken by the standard library "random" module -- take a look at lib/python2.5/random.py in your python directory. At the bottom, it has something like this:

# Create one instance, seeded from current time, and export its methods
# as module-level functions.  [...]
_inst = Random()
seed = _inst.seed
random = _inst.random
uniform = _inst.uniform
...

Or you can take the basic approach you described (though I would recommend using @staticmethod rather than @classmethod in most cases).

Undercharge answered 30/4, 2012 at 17:58 Comment(0)
C
1

You might actually want a singleton class rather than a static class: Making a singleton class in python

Catercousin answered 23/4, 2016 at 12:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.