## Lesson: Syntax Elements of Python Classes
<div style="position: relative; padding-bottom: 64.90384615384616%; height: 0;"><iframe src="https://www.loom.com/embed/836f42f2a3f94e8384a29107873ba535?sid=939b4d2f-b4f8-437c-8fb6-94ee80219e5b" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></iframe></div>
### Specific Syntax Elements of Python Classes
In Python, classes are used to create user-defined data structures. A class defines the attributes and methods of the objects created from it. Here is an overview of the syntax elements you'll encounter when working with Python classes.
### 1. Defining a Class
The `class` keyword is used to define a class. The class name should follow the CapitalizedWords convention.
```python
class MyClass:
pass # Placeholder for an empty class
```
### 2. The `__init__` Method
The `__init__` method is the constructor method for a class. It is called when an instance (object) of the class is created. This method is used to initialize the object's attributes.
```python
class MyClass:
def __init__(self, attribute1, attribute2):
self.attribute1 = attribute1
self.attribute2 = attribute2
```
### 3. Instance Attributes
Instance attributes are variables that are unique to each instance. They are typically initialized in the `__init__` method.
```python
class MyClass:
def __init__(self, name, age):
self.name = name
self.age = age
```
### 4. Class Attributes
Class attributes are variables that are shared across all instances of a class. They are defined within the class but outside any instance methods.
```python
class MyClass:
species = "Human" # Class attribute
def __init__(self, name):
self.name = name # Instance attribute
```
### 5. Methods
Methods are functions defined within a class. They are used to define the behaviors of the objects.
```python
class MyClass:
def __init__(self, name):
self.name = name
def greet(self):
return f"Hello, {self.name}!"
```
### 6. The `self` Parameter
The `self` parameter is a reference to the current instance of the class. It is used to access variables and methods associated with the class instance.
```python
class MyClass:
def __init__(self, name):
self.name = name
def display_name(self):
print(f"Name: {self.name}")
```
### 7. Inheritance
Inheritance allows one class to inherit attributes and methods from another class. The class being inherited from is called the parent or base class, and the class that inherits is called the child or derived class.
```python
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
pass
class Dog(Animal):
def speak(self):
return f"{self.name} says Woof!"
```
### 8. Overriding Methods
A method in a child class can override a method in the parent class. This allows for specific behavior in the child class.
```python
class Animal:
def speak(self):
return "Some sound"
class Dog(Animal):
def speak(self):
return "Woof!"
```
### 9. Encapsulation
Encapsulation involves restricting access to certain attributes and methods. This is typically done by prefixing an attribute or method name with an underscore (`_`) for protected access or double underscore (`__`) for private access.
```python
class MyClass:
def __init__(self, name, age):
self._name = name # Protected attribute
self.__age = age # Private attribute
def get_age(self):
return self.__age # Accessing a private attribute via a public method
```
### 10. Class Methods and Static Methods
- **Class methods** are methods that are bound to the class and not the instance. They can be used to access or modify the class state. They are defined using the `@classmethod` decorator and take `cls` as the first parameter.
```python
class MyClass:
count = 0
def __init__(self):
MyClass.count += 1
@classmethod
def get_count(cls):
return cls.count
```
- **Static methods** are methods that do not depend on the class or instance. They are defined using the `@staticmethod` decorator and do not take `self` or `cls` as the first parameter.
```python
class MyClass:
@staticmethod
def greet():
return "Hello!"
```
### 11. Special Methods (Magic Methods)
Special methods, also known as magic methods or dunder methods, are used to provide special functionality. They are surrounded by double underscores (`__`). Examples include `__str__`, `__repr__`, `__len__`, and `__eq__`.
```python
class MyClass:
def __init__(self, name):
self.name = name
def __str__(self):
return f"MyClass instance with name: {self.name}"
```
### Cheat Sheet
| Syntax Element | Description |
|---------------------|------------------------------------------------------|
| `class` | Defines a new class |
| `__init__` | Constructor method |
| `self` | Refers to the current instance |
| `@classmethod` | Defines a class method |
| `@staticmethod` | Defines a static method |
| `__str__` | String representation method |
| `__repr__` | Official string representation method |
| `_attribute` | Protected attribute |
| `__attribute` | Private attribute |
| `class Attribute` | Class attribute |
### Exercise
Create a Python class that models a simple banking system. The class should have the following features:
- Attributes for the account holder's name, balance, and account number.
- Methods to deposit money, withdraw money, and check the balance.
- Implement encapsulation to ensure the balance cannot be directly accessed from outside the class.
- Include a class method to keep track of the total number of accounts created.
```python
class BankAccount:
total_accounts = 0
def __init__(self, account_holder, initial_balance, account_number):
self.__account_holder = account_holder
self.__balance = initial_balance
self.__account_number = account_number
BankAccount.total_accounts += 1
def deposit(self, amount):
if amount > 0:
self.__balance += amount
return f"Deposited {amount}. New balance is {self.__balance}."
return "Invalid deposit amount."
def withdraw(self, amount):
if 0 < amount <= self.__balance:
self.__balance -= amount
return f"Withdrew {amount}. New balance is {self.__balance}."
return "Invalid withdrawal amount."
def check_balance(self):
return f"Account balance is {self.__balance}."
@classmethod
def get_total_accounts(cls):
return f"Total bank accounts: {cls.total_accounts}"
```
Use this class to create a few accounts and perform some transactions, ensuring all features work correctly.
This covers the syntax elements of Python classes comprehensively. For patterns, we can delve deeper into specific design patterns used in OOP.