113

All of the tutorials I see online show how to create classes with __init__ constructor methods so one can declare objects of that type, or instances of that class.

How do I create a class (static in Java) so that I can access all methods and attributes of that class without having to create new instances/objects?

For example:

class World:

    allElems = []

    def addElem(x):  

        allElems.append(x)

World.addElem(6)
print(World.allElems)

EDIT

class World(object):

    allAirports = []

    @staticmethod
    def initialize():

        f = open(os.path.expanduser("~/Desktop/1000airports.csv"))
        file_reader = csv.reader(f)

        for col in file_reader:

            allAirports.append(Airport(col[0],col[2],col[3]))

error: name 'allAirports' is not defined

Greg Peckory
  • 7,700
  • 21
  • 67
  • 114
  • 6
    Why do you want a static class? What do you want to achieve? - see also: http://stackoverflow.com/q/10388127/562769 – Martin Thoma May 31 '15 at 11:32
  • try - ```World.allAirports.append(....```. – wwii May 31 '15 at 14:21
  • 12
    Don't do this. I don't know what Java has done to your poor soul, but this can only end badly. `allAirports` is not only a transgression of PEP 8, but - _\*gasp!\*_ - a mutable global. Whatever you're trying to achieve, you're trying to acheive the wrong way. – Veedrac Jun 01 '15 at 08:53
  • 3
    Also, use `with` for files. – Veedrac Jun 01 '15 at 08:53
  • 4
    There are valid use cases for regular classes, for static classes and for bare functions. – Jeyekomon Apr 24 '19 at 11:09
  • @Jeyekomon there is no such thing as a static class in python. There are static methods. You could deecide to call static class one that only has static methods, but that would be a convention of your own; there is nothing particular to the type or implementation that makes it distinct to a "regular" class. –  Apr 11 '20 at 12:01
  • @J.C.Rocamonde Of course it is just a shortcut for "class with only static methods". Since this shortcut has already been used here in the question, comments and answers several times, I decided to also use it. – Jeyekomon Apr 12 '20 at 17:50
  • 1
    @Jeyekomon I understand that. I think the point of using that terminology was to refer to the analogy with Java. The way you phrased, however, suggested that there is an actual distinction, and I thought the clarification was worth mentioning. –  Apr 12 '20 at 18:55
  • I found this question because I am wanting a module that needs to get passed some parameters to properly initialize. The reason I don't like using a module is because I have to reference all the variables as global within the module methods since they are outside the individual methods. – scott.se Nov 11 '22 at 19:01

5 Answers5

145

The Pythonic way to create a static class is simply to declare those methods outside of a class (Java uses classes both for objects and for grouping related functions, but Python modules are sufficient for grouping related functions that do not require any object instance). However, if you insist on making a method at the class level that doesn't require an instance (rather than simply making it a free-standing function in your module), you can do so by using the "@staticmethod" decorator.

That is, the Pythonic way would be:

# My module
elements = []

def add_element(x):
  elements.append(x)

But if you want to mirror the structure of Java, you can do:

# My module
class World(object):
  elements = []

  @staticmethod
  def add_element(x):
    World.elements.append(x)

You can also do this with @classmethod if you care to know the specific class (which can be handy if you want to allow the static method to be inherited by a class inheriting from this class):

# My module
class World(object):
  elements = []

  @classmethod
  def add_element(cls, x):
    cls.elements.append(x)
Michael Aaron Safyan
  • 93,612
  • 16
  • 138
  • 200
  • See above in edit, I used this approach and receive error. No idea why :/ – Greg Peckory May 31 '15 at 11:48
  • 6
    Note that _The Pythonic way_ only works for methods and **creates a problem for fields**, since if the user imports the field via `from module import field` they are stuck with the value at the time of importation. – c z Aug 25 '17 at 11:57
  • 3
    Good answer, but does PEP8 weight in into this at all? – radtek Feb 13 '18 at 18:47
  • 1
    Great insight on the Java vs Python 'class' comparison! – Sam Malayek Jul 26 '18 at 17:23
  • *"The Pythonic way to create a static class is simply to declare those methods outside of a class"* Really? But how can one make use of inheritance then? – Hyperplane Jun 30 '21 at 21:50
  • @Hyperplane static methods don't generally use inheritance, certainly not polymorphism. – Paul Rooney Aug 19 '21 at 23:53
  • The pythonic way doesn't provide namespacing of methods that belong together. If I want to use 10 of the methods in that module, I would either have to import them all individually or `import *`. With a static class, you can just import the class and you get all the methods that it scopes. – Tobias Feil Dec 31 '22 at 11:29
  • I don't know if I prefer this with having to use `global stuff` for assignments over a 'static' class. – robsn May 22 '23 at 12:38
22

You could use a classmethod or staticmethod

class Paul(object):
    elems = []

    @classmethod
    def addelem(cls, e):
        cls.elems.append(e)

    @staticmethod
    def addelem2(e):
        Paul.elems.append(e)

Paul.addelem(1)
Paul.addelem2(2)

print(Paul.elems)

classmethod has advantage that it would work with sub classes, if you really wanted that functionality.

module is certainly best though.

Paul Rooney
  • 20,879
  • 9
  • 40
  • 61
19

There are two ways to do that (Python 2.6+):

static method

class Klass(object):
    @staticmethod
    def static_method():
        print "Hello World"

Klass.static_method()

module

your module file, called klass.py

def static_method():
    print "Hello World"

your code:

import klass

klass.static_method()
boaz_shuster
  • 2,825
  • 20
  • 26
10

Ancient thread, but one way to make this work is:

class Static:
  def __new__(cls):
    raise TypeError('Static classes cannot be instantiated')

Then, you can use it like so:

class Foo(Static): ...

Seems the most 'Pythonic' to me, anyway.

Example use case: singleton class where I register handlers for conversion between types.

Cheers!

Barry J. Burns
  • 119
  • 1
  • 4
2

Seems that you need classmethod:

class World(object):

    allAirports = []

    @classmethod
    def initialize(cls):

        if not cls.allAirports:
            f = open(os.path.expanduser("~/Desktop/1000airports.csv"))
            file_reader = csv.reader(f)

            for col in file_reader:
                cls.allAirports.append(Airport(col[0],col[2],col[3]))

        return cls.allAirports
Eugene Soldatov
  • 9,755
  • 2
  • 35
  • 43