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 ?
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.
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.
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 .
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.
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With