feat: add classes and objects lectures (#61327)

Co-authored-by: Dario-DC <105294544+Dario-DC@users.noreply.github.com>
This commit is contained in:
Ilenia 2025-07-21 19:27:29 +02:00 committed by GitHub
parent 19caaaf7e6
commit 1794a243ac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 633 additions and 48 deletions

View File

@ -5,6 +5,19 @@
"blockType": "lecture",
"blockLayout": "challenge-list",
"superBlock": "full-stack-developer",
"challengeOrder": [{ "id": "68420bd261d0d35f61922d4b", "title": "Step 1" }],
"challengeOrder": [
{
"id": "68420bd261d0d35f61922d4b",
"title": "How Do Classes Work and How Do They Differ From Objects?"
},
{
"id": "6874b5fc38f90f25e18093ce",
"title": "What Are Methods and Attributes, and How Do They Work?"
},
{
"id": "6874b7d3b286c538b39d0c25",
"title": "What Are Special Methods and What Are They Used For?"
}
],
"helpCategory": "Python"
}
}

View File

@ -1,137 +1,220 @@
---
id: 68420bd261d0d35f61922d4b
# title needs to be updated to correct title when lectures are finalized
title: Classes and Objects
# change back to 11 when video is added
title: How Do Classes Work and How Do They Differ From Objects?
challengeType: 19
# videoId: new-id-goes-here-when-ready
# dashedName needs to be updated to correct title when lectures are finalized
dashedName: lecture-classes-and-objects
dashedName: how-do-classes-work-and-how-do-they-differ-from-objects
---
# --description--
Watch the video or read the transcript and answer the questions below.
In Python, classes and objects work hand in hand to organize and manage data. You build a class to define shared behavior, then create objects that use those behaviors.
In other words, a class is like a blueprint or template you use to create objects with.
Let's look at what classes are, and how to use them to create objects.
To create a class, you use the `class` keyword followed by the name of the class and a colon. Then within the class, you can add an initializer, along with any attributes and methods.
Attributes are like variables within a class, and are used to store data. Methods are functions defined within a class, and are the actions objects created with a class can perform.
Here's the basic syntax of a class:
```python
class ClassName:
def __init__(self, name, age):
self.name = name
self.age = age
def sample_method(self):
print(self.name.upper())
```
* `class ClassName` is made up of the `class` keyword to create a class, followed by the name of the class, here called `ClassName`. It is common in Python to use the **PascalCase** convention when naming classes.
* `def __init__(self, name, age)` is the special method automatically called when a new object is created. It initializes the attributes of the objects that will be created with the class.
In addition to that, the first parameter of `__init__` is always a reference to the specific object being created or used. By convention, this parameter is named `self`, but technically, you can use any name. `self` lets you access the object's own attributes and methods.
* `self.name = name` and `self.age = age` are the attributes the objects will have.
* `def sample_method(self):` is the method each object created can call.
* `print(self.name.upper())` is what the `sample_method` method will do, in this case, it prints the name in uppercase.
If that all sounds like a lot, don't worry. Let's take a look at a similar example of a `Dog` class, and how you can create objects from that:
```python
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def bark(self):
print(f"{self.name.upper()} says woof woof!")
```
With this `Dog` class, you can create an object. Here's the basic syntax for creating objects from a class:
```python
object_1 = ClassName(attribute_1, attribute_2)
object_2 = ClassName(attribute_1, attribute_2)
```
You can also call any of the methods defined in the class from each object:
```python
object_1.method_name()
object_2.method_name()
```
Now let's create two dogs by using the `Dog` class as the blueprint:
```python
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def bark(self):
print(f"{self.name.upper()} says woof woof! I'm {self.age} years old!")
dog_1 = Dog("Jack", 3)
dog_2 = Dog("Thatcher", 5)
# Call the bark method
dog_1.bark() # JACK says woof woof! I'm 3 years old!
dog_2.bark() # THATCHER says woof woof! I'm 5 years old!
```
As you can see, we create two dog objects using the `Dog` class. When initializing `dog_1`, the string `Jack` and the number `3` are passed, which sets the `name` and `age` attributes for that instance. And `dog_2` is initialized with the string `Thatcher` and number `5` as its `name` and `age`, respectively.
Then when you call the `.bark()` method on `dog_1` and `dog_2`, you can see how both outputs differ, and use the unique `name` and `age` attributes you passed in when creating each object.
In summary, the difference between a class and an object is that a class is the template or the blueprint, and an object is what is created using that template.
Also, a class defines what data and behavior the object should have, and an object holds the actual data and uses that behavior. You write a class once, and you can make many objects from it, each with different data.
# --questions--
## --text--
Question 1
What is the output of this code?
```python
class Dog:
def __init__(self, name):
self.name = name
def bark(self):
print(f"{self.name} says Woof!")
my_dog = Dog("Rex")
print(my_dog.name)
```
## --answers--
Answer 1.1
`Rex says Woof!`
### --feedback--
Feedback 1
Look at what is being printed: is it calling a method or accessing an attribute?
---
Answer 1.2
`name`
### --feedback--
Feedback 1
Look at what is being printed: is it calling a method or accessing an attribute?
---
Answer 1.3
### --feedback--
Feedback 1
`Rex`
---
Answer 1.4
Error
### --feedback--
Feedback 1
Look at what is being printed: is it calling a method or accessing an attribute?
## --video-solution--
5
3
## --text--
Question 2
What is the special method that gets automatically called when a new object is created?
## --answers--
Answer 2.1
`__create_object__`
### --feedback--
Feedback 2
Think about what initializes the attributes an object will have.
---
Answer 2.2
### --feedback--
Feedback 2
`__init__`
---
Answer 2.3
`__new__`
### --feedback--
Feedback 2
Think about what initializes the attributes an object will have.
---
Answer 2.4
`__setup__`
### --feedback--
Feedback 2
Think about what initializes the attributes an object will have.
## --video-solution--
5
2
## --text--
Question 3
What is the blueprint or template for creating objects?
## --answers--
Answer 3.1
A variable
### --feedback--
Feedback 3
Think about what defines the structure and behavior of objects created from it.
---
Answer 3.2
A function
### --feedback--
Feedback 3
Think about what defines the structure and behavior of objects created from it.
---
Answer 3.3
### --feedback--
Feedback 3
A class
---
Answer 3.4
A loop
### --feedback--
Feedback 3
Think about what defines the structure and behavior of objects created from it.
## --video-solution--
5
3

View File

@ -0,0 +1,209 @@
---
id: 6874b5fc38f90f25e18093ce
title: What Are Methods and Attributes, and How Do They Work?
challengeType: 19
dashedName: what-are-methods-and-attributes-and-how-do-they-work
---
# --description--
In the last lecture, you learned about classes and how they act as blueprints for creating objects.
Here, we will dive deeper into attributes and methods.
Let's take a closer look at attributes first, then methods.
Attributes are variables that belong to an object, so they hold data. There are two kinds of attributes: instance attributes and class attributes.
Instance attributes are unique to each object created from a class, and you usually set them with the `__init__` method. Class attributes, on the other hand, belong to the class itself and are shared by all instances of that class.
To access an attribute, you use dot notation.
Here are examples of both instance and class attributes, and how to access them from objects:
```python
class Dog:
species = "French Bulldog" # Class attribute
def __init__(self, name):
self.name = name # Instance attribute
print(Dog.species) # French Bulldog
dog1 = Dog("Jack")
print(dog1.name) # Jack
print(dog1.species) # French Bulldog
dog2 = Dog("Tom")
print(dog2.name) # Tom
print(dog2.species) # French Bulldog
```
Note that you can access class attributes directly from the class itself, but you need to create an object and pass it data first before you can access instance attributes.
Cars are another good example, since all cars have a model and color:
```python
class Car:
def __init__(self, color, model):
self.color = color
self.model = model
car_1 = Car("red", "Toyota Corolla")
car_2 = Car("green", "Lamborghini Revuelto")
print(car_1.model) # Toyota Corolla
print(car_2.model) # Lamborghini Revuelto
print(car_1.color) # red
print(car_2.color) # green
```
Methods are functions defined inside a class. With them, any object defined from a class can perform actions that operate on or modify its own data. You also access a method with dot notation.
For example, dogs can bark. So we can have a `bark` method in the `Dog` class like you saw in a previous lecture:
```python
class Dog:
species = "French Bulldog"
def __init__(self, name):
self.name = name
def bark(self):
return f"{self.name} says woof woof!"
jack = Dog("Jack")
jill = Dog("Jill")
print(jack.bark()) # Jack says woof woof!
print(jill.bark()) # Jill says woof woof!
```
A `Car` class can also have a `describe` method:
```python
class Car:
def __init__(self, color, model):
self.color = color # Instance attribute
self.model = model # Instance attribute
def describe(self):
return f"This car is a {self.color} {self.model}"
car_1 = Car("red", "Toyota Corolla")
car_2 = Car("green", "Lamborghini Revuelto")
print(car_1.describe()) # This car is a red Toyota Corolla
print(car_2.describe()) # This car is a green Lamborghini Revuelto
```
# --questions--
## --text--
What are the two types of attributes in Python?
## --answers--
Public and private attributes
### --feedback--
Think about the two ways you can define attributes.
---
Local and global attributes
### --feedback--
Think about the two ways you can define attributes.
---
Instance attributes and class attributes
---
Mutable and immutable attributes
### --feedback--
Think about the two ways you can define attributes.
## --video-solution--
3
## --text--
What is required to access instance attributes?
## --answers--
The class name only
### --feedback--
Think about how you access class attributes versus how you access instance attributes.
---
Decorators
### --feedback--
Think about how you access class attributes versus how you access instance attributes.
---
An instance or object of the class
---
A static method
### --feedback--
Think about how you access class attributes versus how you access instance attributes.
## --video-solution--
3
## --text--
How do you define and access methods?
## --answers--
As standalone functions outside a class, accessed with brackets
### --feedback--
They belong to the class but operate on object data.
---
As variables in a class, accessed like attributes
### --feedback--
They belong to the class but operate on object data.
---
With special keywords, called automatically
### --feedback--
They belong to the class but operate on object data.
---
They are defined inside a class and accessed with dot notation
## --video-solution--
4

View File

@ -0,0 +1,280 @@
---
id: 6874b7d3b286c538b39d0c25
title: What Are Special Methods and What Are They Used For?
challengeType: 19
dashedName: what-are-special-methods-and-what-are-they-used-for
---
# --description--
Special methods in Python, also known as "magic methods" or "dunder methods", are special Python methods that start and end with double underscores (`__`). The word "dunder" itself comes from double underscores (**d** for double, **under** for underscores).
You've probably used special methods already without knowing it. Every time you write something like `3 + 4`, Python quietly runs `3.__add__(4)` under the hood. That's a special method in action. So while you *can* call special methods directly, you rarely do. Something like `3 + 4` is much clearer and easier to read than calling `3.__add__(4)` yourself.
Apart from `__add__`, `__init__()` is another special method you'll see and use the most, as it's a class initializer. There are also others like `__len__()` and `__str__()`.
Think of special methods as the directors of the activities between a person programming and the Python language interpreter itself.
Remember, you don't need to call special methods directly. Instead, Python automatically calls them when certain actions happen. These operations include:
- **Arithmetic operations like addition, subtraction, multiplication, division, and others**. In addition, `__add__()` is called, `__sub__()` for subtraction, `__mul__()` for multiplication, and `__truediv__()` for division.
- **String operations like concatenation, repetition, formatting, and conversion to text**. `__add__()` is called for concatenation, `__mul__()` for repetition, `__format__()` for formatting, `__str__()` and `__repr__()` for text conversion, and so on.
- **Comparison operations like equality, less-than, greater-than, and others**. `__eq__()` is called for equality checks, `__lt__()` for less-than, `__gt__()` for greater-than, and so on.
- **Iteration operations like making an object iterable and advancing through items**. `__iter__()` is called to return an iterator and  `__next__()` to fetch the next item.
Normally, Python data types like strings and numbers already know how to add things, do concatenation, compare for equality, be used in loops, and others.
But when you create your own class, Python won't know how to handle things automatically.
This is where special methods come in — they let you customize Python's built-in behavior.
Let's say you want to get the number of pages in book objects created with the class below, or compare them and get a readable string of the objects. Here's what happens without special methods:
```python
class Book:
def __init__(self, title, pages):
self.title = title
self.pages = pages
book1 = Book("Built Wealth Like a Boss", 420)
book2 = Book("Be Your Own Start", 420)
print(len(book1)) # TypeError: object of type 'Book' has no len()
print(str(book1)) # <__main__.Book object at 0x102ed2900>
print(book1 == book2) # False even though they have the same number of pages
```
In the example:
- `len(book1)` failed because Python doesn't know how to get the length of your book object without `__len__()`
- `str(book1)` printed something like `<__main__.Book object at 0x102ed2900>` because that's the default representation when you don't use `__str__()`
- `book1 == book2` resulted in `False` because Python just checks if both objects are the same in memory, not by content.
Here's how you can define your own `__len__()`, `__str__()`, and `__eq__()` special methods to make working with objects created from the `Book` class easier:
```python
class Book:
def __init__(self, title, pages):
self.title = title
self.pages = pages
def __len__(self):
return self.pages
def __str__(self):
return f"'{self.title}' has {self.pages} pages"
def __eq__(self, other):
return self.pages == other.pages
book1 = Book("Built Wealth Like a Boss", 420)
book2 = Book("Be Your Own Start", 420)
print(len(book1)) # 420
print(len(book2)) # 420
print(str(book1)) # 'Built Wealth Like a Boss' has 420 pages
print(str(book2)) # 'Be Your Own Start' has 420 pages
print(book1 == book2) # True
```
Another example is a shopping cart where you do the following:
- Add items to the cart
- Remove items from the cart
- Get the number of items in the cart
- Check what items are in the cart
- Check if a specific item is in the cart
- Return or display an item at a specific index in the cart
While you might have a method that adds items to the cart and removes certain items from the cart, you can create special methods for all the other functionality:
- `__len__()` to get the length of the items in the cart
- `__iter__()` to loop through the items in the cart so you can see them
- `__contains__()` to check if a specific item is in the cart
- `__getitem__()` to return or display an item at a specific index in the cart
Here's an example of a `Cart` class with these user-defined methods and special methods:
```python
class Cart:
def __init__(self):
self.items = []
def add(self, item):
self.items.append(item)
def remove(self, item):
if item in self.items:
self.items.remove(item)
else:
print(f'{item} is not in cart')
def list_items(self):
return self.items
def __len__(self):
return len(self.items)
def __getitem__(self, index):
return self.items[index]
def __contains__(self, item):
return item in self.items
def __iter__(self):
return iter(self.items)
```
And here's how you can use them:
```python
cart = Cart()
cart.add('Laptop')
cart.add('Wireless mouse')
cart.add('Ergo keyboard')
cart.add('Monitor')
for item in cart:
print(item, end=' ') # Laptop Wireless mouse Ergo keyboard Monitor
print(len(cart)) # 4
print(cart[3]) # Monitor
print('Monitor' in cart) # True
print('banana' in cart) # False
cart.remove('Ergo keyboard')
print(cart.list_items()) # ['Laptop', 'Wireless mouse', 'Monitor']
cart.remove('banana') # banana is not in cart
```
And those are a few ways you'll use special methods in Python in the real-world.
# --questions--
## --text--
Which of these is the special method called during an addition operation?
## --answers--
`__plus__()`
### --feedback--
Look out for what is triggered when you use the `+` operator.
---
`__sum__()`
### --feedback--
Look out for what is triggered when you use the `+` operator.
---
`__add__()`
---
`__concat__()`
### --feedback--
Look out for what is triggered when you use the `+` operator.
## --video-solution--
3
## --text--
How was the word "dunder" derived?
## --answers--
From "dynamic under-the-hood operations"
### --feedback--
Think about how the word "dunder" is related to how dunder methods are written.
---
From shortening "double underscore" (`__`)
---
From the creator of Python's nickname
### --feedback--
Think about how the word "dunder" is related to how dunder methods are written.
---
From "data under" in reference to hidden methods
### --feedback--
Think about how the word "dunder" is related to how dunder methods are written.
## --video-solution--
2
## --text--
Which special method is called when you use the greater-than (`>`) comparison operator?
## --answers--
`__more__()`
### --feedback--
It stands for "greater than" and is triggered by the `>` operator.
---
`__compare__()`
### --feedback--
It stands for "greater than" and is triggered by the `>` operator.
---
`__greater__()`
### --feedback--
It stands for "greater than" and is triggered by the `>` operator.
---
`__gt__()`
## --video-solution--
4