Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

different values for class variables in each subclass in python

Tags:

python

oop

I have a base class which is never going to be instantiated. There are different subclasses of this base class. Each subclass defines certain class variables where the name is same across all subclasses but the value is going to be different. For example

class Base:
    def display(self): 
        print self.logfile, self.loglevel
class d1(Base):
    logfile = "d1.log"
    loglevel = "debug"
    def temp(self):
        Base.display(self)
class d2(Base):
    logfile = "d2.log"
    loglevel = "info"
    def temp(self):
        Base.display(self)

What is the right way to design this such that I can enforce that if tomorrow any new subclass is defined, the person implementing the subclass should provide some values to these class variables and not miss defining them ?

like image 713
Tanuj Avatar asked Jan 17 '12 10:01

Tanuj


People also ask

What are different class variables in Python?

What is an Class Variable in Python? If the value of a variable is not varied from object to object, such types of variables are called class variables or static variables. Class variables are shared by all instances of a class.

How do you assign a value to a class variable in Python?

Use dot notation or setattr() function to set the value of class attribute. Python is a dynamic language. Therefore, you can assign a class variable to a class at runtime. Python stores class variables in the __dict__ attribute.

Are class variables inherited in Python?

Classes called child classes or subclasses inherit methods and variables from parent classes or base classes. We can think of a parent class called Parent that has class variables for last_name , height , and eye_color that the child class Child will inherit from the Parent .

How instance variables are different from class variables in Python?

Python instance variables can have different values across multiple instances of a class. Class variables share the same value among all instances of the class. The value of instance variables can differ across each instance of a class. Class variables can only be assigned when a class has been defined.


2 Answers

One alternative that doesn't require instantiating the classes for the checking to take place is to create a metaclass:

class BaseAttrEnforcer(type):
    def __init__(cls, name, bases, d):
        if 'loglevel' not in d:
            raise ValueError("Class %s doesn't define loglevel attribute" % name)
        type.__init__(cls, name, bases, d)

class Base(object):
    __metaclass__ = BaseAttrEnforcer
    loglevel = None

class d1(Base):
    logfile = "d1.log"
    loglevel = "debug"

class d2(Base):
    logfile = "d2.log"
    loglevel = "info"

class d3(Base):
    logfile = "d3.log"
    # I should fail
like image 87
Anders Waldenborg Avatar answered Sep 18 '22 02:09

Anders Waldenborg


This should work

>>> class Base(object):
...  def __init__(self):
...   if not hasattr(self, "logfile"):
...    raise Exception("not implemented")
... 
>>> class d1(Base):
...  logfile='logfile1.log'
... 
>>> class d2(Base):
...  pass
... 
>>> d1()
<__main__.d1 object at 0x7d0d0>
>>> d2()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in __init__
not implemented
like image 39
Savino Sguera Avatar answered Sep 22 '22 02:09

Savino Sguera