Class
Writing a small Python program is straightforward. But composing a large program with many features is more difficult—classes can help here.
With classes, we can divide up the features of the program and only change parts at a time. This helps keep the program easy to maintain.
This program creates a class
. It uses the class
keyword and provides two methods. The __init__ method is special. It is a constructor.
class
instance. It can validate arguments, do computations, call methods.class
. Its width is set to 10. And its height is set to 2.area()
method will return 20. This is based on the values stored in memory, set by init
.class Box: def area(self): return self.width * self.height def __init__(self, width, height): self.width = width self.height = height # Create an instance of Box. x = Box(10, 2) # Print area. print(x.area())20
A class
can inherit from one or more other classes. The class
we want to derive from must be defined. The derived class
is specified in the parentheses after the class
name.
Class
B derives from class
A. In the statements after the classes, we call size (from class
B) and width (from class
A).size()
method is found directly on class
B. It does not exist on class
A.Width()
is found by checking the base class
of class
B, which is class
A. Width is a method on class
A.class
inheritance is not possible. If B and A both derive from each other, we will get a NameError
.class A: def width(self): print("a, width called") class B(A): def size(self): print("b, size called") # Create new class instance. b = B() # Call method on B. b.size() # Call method from base class. b.width()b, size called a, width called
In a class
, some members have two underscores at the start of their names. These are special. The Python language treats them as private.
class
, but we must add _ClassName to the start.class
A, we have a field called __value. We must reference this as _A__value outside of the class
, but can use __value inside.class A: # Init. def __init__(self, value): self.__value = value # Two-underscore name. __value = 0 # Create the class. a = A(5) # [1] Cannot use two-underscore name. # print(a.__value) # [2] Must use mangled name. print(a._A__value)5
This determines if one class
is derived from another. With this built-in method, we pass two class
names (not instances).
class
inherits from the second, issubclass returns true. Otherwise it returns false.class
is considered a subclass of itself. The third issubclass call shows this.class A: def hello(self): print("A says hello") class B(A): def hello(self): print("B says hello") # Use the derived class. b = B() b.hello() # See if B inherits from A. if issubclass(B, A): print(1) # See if A inherits from B. if issubclass(A, B): # Not reached. print(2) # See if A inherits from itself. if issubclass(A, A): print(3)B says hello 1 3
When the first argument (a variable) is an instance of the second argument (a class
), isinstance returns true. It will also return true if the class
is a base class
.
class
name may not be specified in the program. But we can still test for "list" this way.class A: def welcome(self): # Not called. print("Welcome") # This is an instance of A. a = A() if isinstance(a, A): print(1) # This is an instance of the list class. b = [1, 2, 3] if isinstance(b, A): # Not reached. print(2) if isinstance(b, list): print(3)1 3
This accesses the __repr__ method from a class
. Repr stands for "representation." It converts an object into a string
representation. Here we display Snake instances in a special way.
string
from the repr method. The print method automatically calls an object's __repr__ method.string
in a variable.class Snake: def __init__(self, type): self.type = type def __repr__(self): return "Snake, type = " + self.type # Create Snake instance. # ... Print its repr. s = Snake("Anaconda") print(s) # Get repr of Snake. value = repr(s) print(value)Snake, type = Anaconda Snake, type = Anaconda
A property gets and sets a value. It is just like a method, but uses simpler syntax. A property can be assigned like a variable. This causes the setter method to be executed.
string
passed to setname.class
instance. Then we assign the "name" property. This invokes the setname method of the Snake class
.class Snake: def getname(self): return self._name def setname(self, value): # When property is set, capitalize it. self._name = value.capitalize() name = property(getname, setname) # Create a snake instance. s = Snake() # Set name property. s.name = "rattle" # Get name property. print(s.name)Rattle
With the super()
built-in, we can get the parent of a class
. This gets the immediate ancestor. Here we call super()
within the Circle class
, which references its parent class
, Shape.
name()
from Shape is also called.class Shape: def name(self): print("Shape") class Circle(Shape): def name(self): print("Circle") # Call name method from parent class. super().name() # Create Circle and call name. c = Circle() c.name()Circle Shape
When comparing objects, a hash code can be used for more speed. A dictionary uses hashes. With __hash__ we implement custom hash computations. A unique value is a good hash.
unique_id
is used to compute the hash.class Snake: def __init__(self, name, color, unique_id): self.name = name self.color = color self.unique_id = unique_id def __hash__(self): # Hash on a unique value of the class. return int(self.unique_id) # Hash now is equal to the unique ID values used. p = Snake("Python", "green", 55) print(hash(p)) p = Snake("Python", "green", 105) print(hash(p))55 105
Every object has an id. This is unique to the instance. Its exact number is an implementation detail and will vary between program executions. Here we look at class
ids.
class Cat: def __init__(self, color): self.color = color cat1 = Cat("black") cat2 = Cat("orange") # Each object has a unique id. # ... The ids may vary between runs. print(id(cat1)) print(id(cat2))4353403328 4353403384
staticmethod
Python supports special method types (like static
methods). These are class
methods and static
methods.
Built-in methods can create and modify types with statements. The type built-in can replace the "class
" declaration. With setattr and getattr we add or load fields.
In a Python class
, we store data in fields. And we also provide method implementations, as with the ref
-keyword. This provides an important level of abstraction.