pythonplonederived-classbase-class

how to get derived class name from base class


I have a base class Person and derived classes Manager and Employee. Now, what I would like to know is the object created is Manager or the Employee.

The person is given as belows:

from Project.CMFCore.utils import getToolByName
schema = getattr(Person, 'schema', Schema(())).copy() + Schema((TextField('FirstName', required = True, widget = StringWidget(label='First Name', i18n_domain='project')), TextField('Last Name', required = True, widget = StringWidget(label='Last Name', i18n_domain='i5', label_msgid='label_pub_city'))
class Manager(BaseContent):
  def get_name(self):
    catalog = getToolByName(self, "portal_catalog")
      people = catalog(portal_type='Person')
      person={}
      for object in people:
        fname = object.firstName
        lname = object.lastName
        person['name'] = fname+' '+ lname
        # if the derived class is Employee then i would like go to the method title of employee and if its a Manager then go to the title method of Manager
        person['post'] = Employee/Manager.title()
      return person

For Manager and employees they are like (employee is also similar but some different methods)

from Project.Person import Person
class Manager(Person):
    def title(self):
      return "Manager"

For Employee the title is 'Employee'. When I create a Person it is either Manager or the Employee. When I get the person object the class is Person but I would like to know whether it is from the derived class 'Manager' or 'Employee'.


Solution

  • You can use x.__class__.__name__ to retrieve the class name as a string, e.g.

    class Person:
        pass
    
    class Manager(Person):
        pass
    
    class Employee(Person):
        pass
    
    def get_class_name(instance):
        return instance.__class__.__name__
    
    >>> m = Manager()
    >>> print get_class_name(m)
    Manager
    >>> print get_class_name(Employee())
    Employee
    

    Or, you could use isinstance to check for different types:

    >>> print isinstance(m, Person)
    True
    >>> print isinstance(m, Manager)
    True
    >>> print isinstance(m, Employee)
    False
    

    So you could do something like this:

    def handle_person(person):
        if isinstance(person, Manager):
            person.read_paper()     # method of Manager class only
        elif isinstance(person, Employee):
            person.work_hard()      # method of Employee class only
        elif isinstance(person, Person):
            person.blah()           # method of the base class
        else:
            print "Not a person"