# Class template for beginners

I want to allow anyone that has never coded to make classes depending on my template with little to no knowledge of Python.

These classes need to do 2 things:

• Inherit from other classes similar to them.
• Contain variables, updating values if they have been changed or keeping them if not.

For the sake of simplicity I don't want to have super() on these new classes, as I'm trying to not frighten newcomers with things they can't understand yet. Here's how I did it:

class Template(object):

def __init__(self):
self.value = "hello"
self.other_value = "bonjour"
self.constant_value = 42
current_class = self.__class__
inits = []
while (current_class.__name__ != "Template"):
inits.append(current_class.init)
current_class = current_class.__bases__[0]
for i in reversed(inits):
i(self)

def init(self):
pass

def info(self):
print self.value
print self.other_value
print self.constant_value
print ""

class Deep(Template):
def init(self):
self.value = "howdy"
self.other_value = "salut"

class Deeep(Deep):
def init(self):
self.value = "hi"

class Deeeep(Deeep):
def init(self):
self.value = "'sup"

very_deep = Deeeep()
not_so_deep = Deep()
very_deep.info()
not_so_deep.info()


This outputs :

sup
salut
42

howdy
salut
42


Which is exactly what I want, but it looks really weird, obfuscated and non-Pythonic. Any ideas for improvements?

• Could you please explain a little bit more how a novice is supposed to use the Template class? Should they create their own classes which inherit from Template, or should they simply make a copy of the code and modify it to their needs? In either case I don't understand how this is going to be easier for them than just learning to actually write their own class which does what they need. – mkrieger1 Dec 9 '16 at 11:46
• The output should really be 'sup, not sup. That has mistakenly been changed in rev. 2, but I can't fix it because it's only a single-character edit. – mkrieger1 Dec 9 '16 at 11:52

Instead of managing the class hierarchy yourself, you should rely on Python's standardized way of doing it: the MRO. You can reach every class in the hierarchy using it without falling in the trap of forgetting some when dealing with multiple inheritance (which your code does):

class Template(object):
def __init__(self):
self.value = "hello"
self.other_value = "bonjour"
self.constant_value = 42

for cls in reversed(self.__class__.mro()):
if hasattr(cls, 'init'):
cls.init(self)


However, if your plan is to make support for the call of super() on init without the user explicitly calling it, I would advise to put the initialization stuff in init as well:

class Template(object):
def __init__(self):
for cls in reversed(self.__class__.mro()):
if hasattr(cls, 'init'):
cls.init(self)

def init(self):
self.value = "hello"
self.other_value = "bonjour"
self.constant_value = 42


This:

...
while (current_class.__name__ != "Template"):
...


is weird. Do this:

...
while current_class != Template:
...


it does the same, except comparing classes instead of strings.

This is strange as well:

for i in reversed(inits):
i(self)


i is used for iteration so it becomes obsucre, are you calling an int? This:

for init in reversed(inits):
init(self)


is more explanatory.

extract_first = lambda x: x[0]


with an explanatory name, leaving that part of the code as this:

extract_first = lambda x: x[0]

while current_class != Template:
inits.append(current_class.init)
current_class = extract_first(current_class.__bases__)
for init in reversed(inits):
init(self)


It leaves it with more words and text but less programming lingo. Might be good.

Now what I would do if this was for someone new to programming is relay on something else then abstraction of the init and abstract in something like biology:

class Exists(object):
perceptible = True

class Alive(Exists):
can_use_sustenance = True

class Vertebrate(Alive):
can_move = True

class Mammal(Vertebrate):
heat_generation = True

class Dog(Mammal):
pass

class Cat(Mammal):
pass


Tested on my significant other :-)