repl.it
Python

No description

fork
loading
Files
  • main.py
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
"""
We’ve looked at how we can define classes and methods, including some special methods like `__init__` and `__len__`.

All these methods had something in common: the `self` parameter at the start. As a reminder, here’s some code:
"""

class Student:
    def __init__(self, name, school):
        self.name = name
        self.school = school
        self.marks = []

    def average(self):
        return sum(self.marks) / len(self.marks)

"""
When we create a new object from the `Student` class and we call a method, we are automagically passing in the `self` parameter:
"""

rolf = Student('Rolf', 'MIT')

rolf.marks.append(78)
rolf.marks.append(99)

print(rolf.average())

"""
This is identical to that last line:
"""

print(Student.average(rolf))

"""
When we do `object.method()`, Python is in the background calling `Class.method(object)`, so that `self` is always the object that called the method.

Indeed, if we were to have two objects:
"""

rolf = Student('Rolf', 'MIT')
anne = Student('Anne', 'Cambridge')

rolf.marks.append(78)
rolf.marks.append(99)

anne.marks.append(34)
anne.marks.append(56)

print(rolf.average())
print(anne.average())

"""
In the first case, `self` would be the `rolf` object, and in the second case `self` would be the `anne` object.

Notice that this knowledge now lets us do some very weird stuff (not recommended, as it’ll likely break things):
"""

Student.average('hello')  # self is now 'hello', comment this out to run the rest of the file.

"""
Just remember `self` is a parameter like any other; and you can give it any value you want. However, because the method is then accessing `’hello’.marks`, you’ll get an error for the string doesn’t have that property.

Anyway, so why is this important?

The first type of method we’ve looked at is called “instance method”: one that takes the caller object as the first argument (that’s `self`).

There are two more types of method:

* One that takes the caller’s class as the first argument; and
* One that takes nothing as the first argument.
"""

## @classmethod
"""
Let’s look at the one that takes the caller’s class as the first argument.
"""

class Foo:
  @classmethod
  def hi(cls):
    print(cls.__name__)

my_object = Foo()
my_object.hi()  # prints Foo

## @staticmethod
"""
Now one that takes nothing as the first argument.
"""

class Foo:
  @staticmethod
  def hi():
    print("I don't take arguments!")

my_object = Foo()
my_object.hi()

"""
Those are some terrible examples! Let’s look at some more in the next section.
"""