Question

from __future__ import print_function

class Employee:
    def __init__(self, name, salary=0):
        self.name = name
        self.salary = salary
    def giveRaise(self, percent):
        self.salary = self.salary + (self.salary * percent)
    def work(self):
        print(self.name, "does stuff")
    def __repr__(self):
        return "<Employee: name=%s, salary=%s>" % (self.name, self.salary)


class Chef(Employee):
    def __init__(self, name) :
        Employee.__init__(self, name, 50000)

    def work(self) :
        print(self.name, "makes food")


class Server(Employee):
    def __init__(self, name):
        Employee.__init__(self, name, 40000)
    def work(self):
        print(self.name, "interfaces with customer")

class PizzaRobot(Chef):
    def __init__(self, name):
        Chef.__init__(self, name)
    def work(self):
        print(self.name, "makes pizza")


if __name__ == "__main__":
    for klass in Employee, Chef, Server, PizzaRobot:
        obj = klass(klass.__name__)
        obj.work()

In above code I am not able to understand how last 3 lines behaves whether klass would be a class or it would be an instance of class. if its an class then what below line means and why it is required?

obj = klass(klass.__name__) 
Was it helpful?

Solution

As mentioned there's no iterator here, but a tuple of classes. The loop below will loop over each class and instantiate a new object for each of the classes.

for klass in Employee, Chef, Server, PizzaRobot:
    obj = klass(klass.__name__)
    obj.work()

If you look at your class definitions and specifically the __init__-function for each class, you'll see that there's a positional argument name:

class Chef(Employee):
    def __init__(self, name): # <-- look here.

Which means that each of your classes must be instantiated with a parameter name:

>>> john = Chef('John')
>>> print(john)
<Employee: name=John, salary=50000>

Each class has a __name__ attribute, which is the defined name for that class. For example Chef.__name__ is Chef:

>>> Chef.__name__
'Chef'

This is different from the name parameter you've defined for your classes, as this is an internal attribute and should not be changed.

Thus the line obj = klass(klass.__name__) will create an object for each the classes you're looping over and give the class __name__ attribute as the positional argument name for each object.

You will end up with four objects of types Employee, Chef, Server and PizzaRobot. Instead of human names like John as per the example I've given, you're just naming them after the class.

>>> for klass in Employee, Chef, Server, PizzaRobot:
...     print(klass.__name__)
...    
Employee
Chef
Server
PizzaRobot
>>>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top