Classes in Python are defined using the
class keyword. The indented lines that follow the keyword are part of the class definition.
class Horse: # lines here are part of the definition of class Horse.
Initializers, Methods, and Instance Variables
In Python, the class definition typically contains function definitions (“methods” in object-oriented parlance) that define the “behavior” of instances of the class. A special function, named
__init__(...), is used to initialize new instances of the class when they are created.
class Horse: def __init__(self, color="sorrel"): self.color = color
The first parameter to all methods in a class is a reference to the instance (object) of the class being manipulated. By Python convention, this parameter is named
self, but it doesn’t really matter to the Python compiler. In other object-oriented languages, like Java and C++, this parameter is implicit (not specified explicitly) and instead the reserved word
this is used to reference the current object.
Using this very short class definition, it is possible to create multiple horses with different colors.
silver = Horse("white") trigger = Horse("palomino") wilbur = Horse("palomino") buck = Horse("buckskin") secretariat = Horse()
If the color is not specified in the contructor (e.g., the
secretariat example), the default color (“sorrel”) is used.
self.color = color
assigns to the instance of the variable
color associated with the current object (
self), the value of the specified parameter named
color. Note that instance variable names and parameter names can be the same; using the dot notation is needed to disambiguate them.
prints “palomino” to the console.
Instance variables are not declared in Python (unlike Java and C++). They are created automatically by references to
self. These references can be in the initializer method (__init__), in some other method, or just in code that references an instance of that class.
Consider this expanded
class Horse: def __init__(self, color="sorrel"): self.color = color def setBreed(self, breed): self.breed = breed; silver = Horse("white") trigger = Horse("palomino") wilbur = Horse("palomino") buck = Horse("buckskin") print(trigger.color) trigger.setBreed("grade") print(trigger.breed) trigger.gender = "stallion" print(trigger.gender)
color instance variable is set in the initializer method, so that all instances of the
Horse class have a color, even if
Horse() is called with no arguments (defaulting to “sorrel”).
breed instance variable is created and set by the
gender instance variable is created and set by this code inline.
Note that instance variables are created dynamically when assigned a value. If no value is assigned, no instance variable is created. So, for example, the code sequence:
flicka = Horse() print(flicka.color) print(flicka.breed)
Prints “sorrel”, but then crashes with the error “AttributeError: Horse instance has no attribute ‘breed'”. Since the
setBreed(...) method was not called on the object referenced by
flicka, nor was the
breed variable explicitly set, the instance variable did not exist. Note that the error message says the Horse instance has no attribute ‘breed’. This phrasing is precise, since it says that the attribute is missing in this particular instance (object).
A typical convention is to assign values to all instance variables in the initializer, which forms a kind of documentation–identifying which variables the class is expecting to see in each instance. For example, the
Horse initializer could be rewritten as
def __init__(self, color="sorrel"): self.color = color self.breed = "unknown" self.gender = None
indicating that (1) the color can be specified as an initializer parameter, but defaults to “sorrel”, (2) the breed is “unknown”, and (3) the gender is not set to any value (
None). Even though the gender is not set, it does exist as a variable in the class instances, so accessing it no longer gives an error, returning
Instance Variables and Class Variables
Variables declared at the “top level” in a class are attributes of the class–the same variable is common to all instances. Class variables are most commonly referenced using dot notation with the class name, e.g.,
Horse.herd_size (see below). The variable can also be referenced through an instance, however, assigning this variable a value in this way creates a new copy of that variable local to the instance. This feature in Python can be confusing, especially for students familiar with Java or C++.
For example, we can modify the
Horse class to keep track of the herd size by introducing a class variable,
class Horse: herd_size = 0 def __init__(self, color="sorrel"): Horse.herd_size += 1 self.color = color self.breed = "unknown" self.gender = None
After creating several instances of
Horse, we can access the
herd_size variable to see how many there are:
silver = Horse("white") trigger = Horse("palomino") wilbur = Horse("palomino") buck = Horse("buckskin") secretariate = Horse() print(Horse.herd_size)
We can access the class variable through an instance, for example:
also prints 5. However, if we attempt to modify the variable through an instance, a new (local) copy of the variable is created instead:
silver.herd_size = 0; print(silver.herd_size) print(Horse.herd_size) sea_biscuit = Horse() print(trigger.herd_size)
prints 0, 5, 6. The object referenced by silver now has a local copy of the
herd_size variable, but the
Horse class variable is unaffected, as are instances of
Horse that have not created their own local copies.
Private Variables and Methods
The Python language does not directly support private variables and methods in the Java/C++ sense–that is, variables that are not accessible by “clients” of the class. However, there is a common convention used in Python: variables and methods that begin with a underscore (“_”) are considered private and are not to be referenced outside the class.