Idan
Idan

Reputation: 5735

Class constants in Python

In Python, I want a class to have some "constants" (practically, variables) which will be common in all subclasses.

Is there a way to do it with friendly syntax? Right now I use:

class Animal:
    SIZES=["Huge","Big","Medium","Small"]

class Horse(Animal):
    def printSize(self):
        print(Animal.SIZES[1])

and I'm wondering if there is a better way to do it?
or a way to do it without then having to write "Animal." before the sizes.

Horse inherits from Animal.

Upvotes: 204

Views: 389127

Answers (5)

Nothingness
Nothingness

Reputation: 1

You can also use an Enum to achieve constants:

from enum import Enum, IntEnum

class MyEnumA(Enum):
    A = "A"
    B = "B"
    C = "C"
    D = "D"
    E = "E"

class MyEnumB(IntEnum):
    A = 0
    B = 1
    C = 2
    D = 3
    E = 4

Upvotes: 0

betabandido
betabandido

Reputation: 19704

Since Horse is a subclass of Animal, you can just change

print(Animal.SIZES[1])

with

print(self.SIZES[1])

Still, you need to remember that SIZES[1] means "big", so probably you could improve your code by doing something like:

class Animal:
    SIZE_HUGE="Huge"
    SIZE_BIG="Big"
    SIZE_MEDIUM="Medium"
    SIZE_SMALL="Small"

class Horse(Animal):
    def printSize(self):
        print(self.SIZE_BIG)

Alternatively, you could create intermediate classes: HugeAnimal, BigAnimal, and so on. That would be especially helpful if each animal class will contain different logic.

Upvotes: 204

Matthew Trevor
Matthew Trevor

Reputation: 14952

Expanding on betabandido's answer, you could write a function to inject the attributes as constants into the module:

def module_register_class_constants(klass, attr_prefix):
    globals().update(
        (name, getattr(klass, name)) for name in dir(klass) if name.startswith(attr_prefix)
    )

class Animal(object):
    SIZE_HUGE = "Huge"
    SIZE_BIG = "Big"

module_register_class_constants(Animal, "SIZE_")

class Horse(Animal):
    def printSize(self):
        print SIZE_BIG

Upvotes: 6

Fred Foo
Fred Foo

Reputation: 363467

You can get to SIZES by means of self.SIZES (in an instance method) or cls.SIZES (in a class method).

In any case, you will have to be explicit about where to find SIZES. An alternative is to put SIZES in the module containing the classes, but then you need to define all classes in a single module.

Upvotes: 28

amit kumar
amit kumar

Reputation: 21012

class Animal:
    HUGE = "Huge"
    BIG = "Big"

class Horse:
    def printSize(self):
        print(Animal.HUGE)

Upvotes: 21

Related Questions