A class is a blueprint for creating objects. It's a fundamental concept in Object-Oriented Programming (OOP) that allows you to bundle data (attributes) and the functions that operate on that data (methods) into a single, organized unit. The LogFile class in your Canvas is a perfect example of this.
1. Defining a Class
You define a class using the class keyword. This creates a new data type, allowing you to create "instances" or objects of that type.
- Use Case: To model a real-world concept, like a user, a car, or, as in your Canvas, a log file.
Python
# --- Defining a Class ---
# This creates a blueprint for a 'Dog'.
class Dog:
# Class attribute (shared by all instances)
species = "Canis familiaris"
# The constructor method (explained next)
def __init__(self, name, age):
# Instance attributes (unique to each instance)
self.name = name
self.age = age
# A method (a function inside a class)
def bark(self):
return "Woof!"
2. The Constructor (__init__) and Instance Attributes
The __init__ method is a special method called a constructor. It's automatically run whenever you create a new instance of the class. Its primary job is to initialize the object's attributes.
Instance attributes are variables that belong to a specific instance of a class. Each object gets its own copy of these attributes.
- Use Case: To set the initial state of an object when it's created. In the LogFile class, this is where the filename is set.
Python
# --- Creating an Instance ---
# This calls the Dog class's __init__ method.
# 'my_dog' is an instance of the Dog class.
my_dog = Dog("Buddy", 3)
# Accessing instance attributes
print(f"My dog's name is {my_dog.name}.") # Output: Buddy
print(f"My dog's age is {my_dog.age}.") # Output: 3
3. The self Variable
The self parameter, which is the first parameter of every method in a class, is a reference to the current instance of the class. Python automatically passes this for you when you call a method on an object. It's how the object's methods can access its own attributes.
- Use Case: To access or modify the instance's own data from within its methods. In the LogFile class, self.filename and self.file are used to refer to the specific file that the LogFile object is managing.
Python
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
# 'self' allows this method to access the 'name' of the specific dog instance.
def get_details(self):
return f"{self.name} is {self.age} years old."
my_dog = Dog("Buddy", 3)
print(my_dog.get_details()) # Python passes 'my_dog' as the 'self' argument automatically.
4. Methods
Methods are functions that are defined inside a class. They operate on the data (attributes) of an instance of that class.
- Use Case: To define the behaviors of your object. The LogFile class has a .write_log() method, which is a specific action that a LogFile object can perform.
Python
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
# This is a method that defines a behavior for a Dog object.
def bark(self):
return f"{self.name} says Woof!"
my_dog = Dog("Buddy", 3)
print(my_dog.bark()) # Calling the bark method on the my_dog instance.
5. Special Methods (Dunder Methods)
Python has a set of special methods with double underscores (e.g., __init__, __repr__) that allow you to integrate your custom objects with Python's built-in syntax and features.
- __repr__(self): Defines the "official" string representation of an object, which is very useful for debugging.
Python
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f"Dog(name='{self.name}', age={self.age})"
my_dog = Dog("Buddy", 3)
print(my_dog) # This calls the __repr__ method.
- __enter__ and __exit__: As seen in your LogFile example, these methods implement the context management protocol, allowing your object to be used with the with statement. This is a powerful way to manage resources that need to be set up and torn down.
- __iter__: As also seen in your LogFile example, this method makes your object iterable, meaning you can use it in a for loop.