Skip to content Skip to sidebar Skip to footer

Python Class Vs. Module Attributes

I'm interested in hearing some discussion about class attributes in Python. For example, what is a good use case for class attributes? For the most part, I can not come up with a c

Solution 1:

#4: I never use class attributes to initialize default instance attributes (the ones you normally put in __init__). For example:

classObj(object):def__init__(self):
        self.users = 0

and never:

classObj(object):
    users =0

Why? Because it's inconsistent: it doesn't do what you want when you assign anything but an invariant object:

classObj(object):
    users = []

causes the users list to be shared across all objects, which in this case isn't wanted. It's confusing to split these into class attributes and assignments in __init__ depending on their type, so I always put them all in __init__, which I find clearer anyway.


As for the rest, I generally put class-specific values inside the class. This isn't so much because globals are "evil"--they're not so big a deal as in some languages, because they're still scoped to the module, unless the module itself is too big--but if external code wants to access them, it's handy to have all of the relevant values in one place. For example, in module.py:

classObj(object):
    classException(Exception): pass
    ...

and then:

from module import Obj

try:
    o = Obj()
    o.go()
except o.Exception:
    print"error"

Aside from allowing subclasses to change the value (which isn't always wanted anyway), it means I don't have to laboriously import exception names and a bunch of other stuff needed to use Obj. "from module import Obj, ObjException, ..." gets tiresome quickly.

Solution 2:

what is a good use case for class attributes

Case 0. Class methods are just class attributes. This is not just a technical similarity - you can access and modify class methods at runtime by assigning callables to them.

Case 1. A module can easily define several classes. It's reasonable to encapsulate everything about class A into A... and everything about class B into B.... For example,

# module xxxclassX:
    MAX_THREADS = 100
    ...

# main programfrom xxx import X

if nthreads < X.MAX_THREADS: ...

Case 2. This class has lots of default attributes which can be modified in an instance. Here the ability to leave attribute to be a 'global default' is a feature, not bug.

classNiceDiff:
    """Formats time difference given in seconds into a form '15 minutes ago'."""

    magic = .249
    pattern = 'in {0}', 'right now', '{0} ago'

    divisions = 1# there are more default attributes

One creates instance of NiceDiff to use the existing or slightly modified formatting, but a localizer to a different language subclasses the class to implement some functions in a fundamentally different way and redefine constants:

classРазница(NiceDiff): # NiceDiff localized to Russian'''Из разницы во времени, типа -300, делает конкретно '5 минут назад'.'''

    pattern = 'через {0}', 'прям щас', '{0} назад'

Your cases:

  • constants -- yes, I put them to class. It's strange to say self.CONSTANT = ..., so I don't see a big risk for clobbering them.
  • Default attribute -- mixed, as above may go to class, but may also go to __init__ depending on the semantics.
  • Global data structure --- goes to class if used only by the class, but may also go to module, in either case must be very well-documented.

Solution 3:

Class attributes are often used to allow overriding defaults in subclasses. For example, BaseHTTPRequestHandler has class constants sys_version and server_version, the latter defaulting to "BaseHTTP/" + __version__. SimpleHTTPRequestHandler overrides server_version to "SimpleHTTP/" + __version__.

Solution 4:

Encapsulation is a good principle: when an attribute is inside the class it pertains to instead of being in the global scope, this gives additional information to people reading the code.

In your situations 1-4, I would thus avoid globals as much as I can, and prefer using class attributes, which allow one to benefit from encapsulation.

Post a Comment for "Python Class Vs. Module Attributes"