# classes.py ''' Introduction into python classes and objects. ''' # # Classes Basics. # # Define a new class. class MyClass(object): """ A simple class test. """ # One only can add class attributes (members) here. i = 1 # This will not be printed. print('Initiating class.') # Define a method of this class. def f(self): ''' Just returns a string. ''' return 'This is MyClass.' # As for function definitions, class definitions define a new namespace. # It is PEP 8 convention to use CamelCase for class names. # Instantiate class, i.e. create an object of the class. my_object = MyClass() # Access its attributes and methods. my_object.i my_object.f() help(my_object) help(MyClass) help(my_object.f) # Using the __init__ methods we can execute code when the class # is being instantiated. class Complex(object): """ A Class with an __init__ method (always do that). """ def __init__(self, a, b=1): """ Set some default values. """ self.x = a**2 + b**2 self.y = a + b my_object = Complex(a=5, b=3) print(my_object.x) print(my_object.y) # Change the attributes. my_object.x = 1 # The first argument of class methods is the object itself. # This is usually called 'self', but can be called any name. # However, it is convention to use 'self'. # The __init__ method is not directly callable. # This will not work: my_object(5, 3) # Create more than one instance of class. o1 = Complex(5, 3) o2 = Complex(5, 1) print(o1.x, o1.y) print(o2.x, o2.y) # Avoid mutable object as attributes, since they are shared between instances. class Dog(object): tricks = [] # mistaken use of a class variable def __init__(self, name): self.name = name def add_trick(self, trick): self.tricks.append(trick) d = Dog('Fido') e = Dog('Buddy') d.add_trick('roll over') e.add_trick('play dead') d.tricks # unexpectedly shared by all dogs # Better: class Dog(object): """Dog Class (who would have thought).""" def __init__(self, name): """Sets the name and tricks.""" self.name = name self.tricks = [] # creates a new empty list for each dog def add_trick(self, trick): self.tricks.append(trick) d = Dog('Fido') e = Dog('Buddy') d.add_trick('roll over') e.add_trick('play dead') d.tricks e.tricks # Call other methods of the class. class Bag(object): def __init__(self): self.data = [] def addtwice(self, x): self.add(x) self.add(x) def add(self, x): self.data.append(x) # Python does not know about private attributes or methods. # To make them less visible, one can start the name by two underscores. # Check if object is of class. isinstance(d, Dog) # # Accessing additional information. # waldo = Dog() # Show the underliyng class. waldo.__class__ # show the attributes and their values as dictionary. waldo.__dict__ # Show a list of all attributes and methods. waldo.__dir__() # Show the class doc string. waldo.__doc__ # # Manually get, set and delete attributes. # waldo = Dog('Waldo') getattr(waldo, 'name') setattr(waldo, 'name', 'Waldo II') setattr(waldo, 'age', 5) print(waldo.age) setattr(waldo, 'sin', np.sin) waldo.sin(np.pi/2) delattr(waldo, 'sin') # # Empty classes can be used to create object that can be # amended manually with attributes and methods. # class Employee: pass john = Employee() # Create an empty employee record # Fill the fields of the record john.name = 'John Doe' john.dept = 'computer lab' john.salary = 1000 # # Inheritance # # Inherite methods and attributes from a base class. class Felines(object): """Feline Class""" def __init__(self): """Initialize parameters.""" self.legs = 4 self.name = "Generic Feline" self.speed = 0 def run(self): """Run feline, run!""" print(self.name + " is running at {0} km/h.".format(self.speed)) class Tigers(Felines): """Tiger Class""" def __init__(self): """Initialize tiger characteristics.""" Felines.__init__(self) self.name = "Generic Tiger" self.speed = 30 self.stripes = 12 def roar(self): print("rrroarrr!!!") class Lions(Felines): """Lions Class""" def __init__(self): """Initialize lion characteristics.""" Felines.__init__(self) self.name = "Generic Lion" self.speed = 35 self.shade_yellow = 'light' def roar(self): print('RRRROARRRR!!!') def run(self): print("Lion {0} is running at {1} km/h.".format(self.name, self.speed)) fel = Felines() fel.speed = 5 fel.name = 'Ginger Cat' fel.run() # Classes inherit from their base class. tig = Tigers() tig.roar() tig.run() # Derived methods override base methods. leo = Lions() leo.name = 'Simba' leo.run() # Check if class is derived from a base class. issubclass(Tigers, Felines)