HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Proper use of class constants

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
properuseclassconstants

Problem

This question specifically relates to the use of the class constants ABOVE and BELOW in the sample code below.

I have a few different classes that look like this:

class MyClass(object):
    ABOVE = 1
    BELOW = 0

    def __init__(self):
        self.my_numbers = [1,2,3,4,5]

    def find_thing_in_direction(self, direction, cutoff):
        if direction == self.ABOVE:
            return [n for n in self.my_numbers if n > cutoff]
        else:
            return [n for n in self.my_numbers if n < cutoff]

my_class = MyClass()
my_var = my_class.find_thing_in_direction(MyClass.ABOVE, 3)


If I have a handful of classes scattered across different .py files that each have their own ABOVE and BELOW, should I extract these constants to somewhere, or is it better to keep the constants within their own classes?

Is there a more Pythonic way to do this instead of using these class constants?

Solution

I think the answer depends on the scope of your constants.

If you're trying to keep the constants the same across your handful of classes, i.e., you have many class definitions and they all use ABOVE and BELOW, and ABOVE and BELOW always have the same value, then you should pull them out. You could put them into a base class and create subclasses from that base class:

class myBaseClass(object):
    ABOVE = 1
    BELOW = 0

class mySubclass(myBaseClass):
    """ ABOVE and BELOW will be available here """
    pass


If the scope is greater than that, say module-level then put the definitions in the module __init__.py

Greater still? Then maybe move them to a settings file.

Otherwise if the scope is where you currently have it then it's ok as-is.

The line:

my_var = my_class.find_thing_in_direction(MyClass.ABOVE, 3)


puzzles me because you're referring to the constant of the Class when the instance already has it itself. It's not wrong, just differs from my reaction to use the object's own attributes:

my_var = my_class.find_thing_in_direction(my_class.ABOVE, 3)


If you go the way of a base class, have a look at ABCs

Code Snippets

class myBaseClass(object):
    ABOVE = 1
    BELOW = 0


class mySubclass(myBaseClass):
    """ ABOVE and BELOW will be available here """
    pass
my_var = my_class.find_thing_in_direction(MyClass.ABOVE, 3)
my_var = my_class.find_thing_in_direction(my_class.ABOVE, 3)

Context

StackExchange Code Review Q#43619, answer score: 9

Revisions (0)

No revisions yet.