16.4. OOP Method
Methods are functions in the class
Prevents copy-paste code
Improves readability
Improves refactoring
Decomposes bigger problem into smaller chunks
At definition -
self
should always be a first parameterAt call -
self
is not passed as an argument (Python will do that)
- method
Functions in the class which takes instance as first argument (
self
)- self
Instance on which method was called.
16.4.1. Define
At definition -
self
should always be a first parameter
>>> class User:
... def login(self):
... print('ok')
Name self
is just a convention. You can use any name you want,
but it is recommended to use self
.
>>> class User:
... def login(this): # this is not recommended
... print('ok')
16.4.2. Call
At call -
self
is not passed as an argument (Python will do that)Methods must be called on an instance
Methods cannot be called on a class
In future you will learn about static-methods and class-methods
>>> class User:
... def login(self):
... print('ok')
Methods must be called on an instance:
>>> mark = User()
>>> mark.login()
ok
Methods cannot be called on a class:
>>> User.login()
Traceback (most recent call last):
TypeError: User.login() missing 1 required positional argument: 'self'
In future you will learn about static-methods and class-methods
16.4.3. Return
Return works the same as in functions
>>> class User:
... def login(self):
... return 'ok'
...
>>>
>>> mark = User()
>>> result = mark.login()
>>>
>>> print(result)
ok
16.4.4. Parameters
At definition -
self
should always be a first parameterLater you will learn more advanced things like static methods etc.
Parameter - Receiving variable used within the function
Works exactly the same as in functions
Parameters could be required or default
Required parameter:
Necessary to call that function
Specified at leftmost side
Default parameter:
Optional to call that function
Default value will be overridden if specified at a call time
Specified at rightmost side
No parameters:
>>> class User:
... def login(self):
... ...
Required parameters:
>>> class User:
... def login(self, username, password):
... ...
Default parameters:
>>> class User:
... def login(self, username=None, password=None):
... ...
Required and Default Parameters:
>>> class User:
... def login(self, username, password=None):
... ...
16.4.5. Arguments
At call -
self
is not passed as an argument (Python will do that)Works exactly the same as in functions
Positional arguments
Keyword arguments
Positional and keyword arguments
SetUp:
>>> class User:
... def login(self, username, password=None):
... ...
>>>
>>> mark = User()
Positional arguments:
>>> mark.login('mwatney')
>>> mark.login('mwatney', 'Ares3')
Keyword arguments:
>>> mark.login(username='mwatney', password='Ares3')
Positional and keyword arguments:
>>> mark.login('mwatney', password='Ares3')
16.4.6. Raise
Return works the same as in functions
>>> class User:
... def login(self, username, password):
... if not (username == 'mwatney' and password == 'Ares3'):
... raise PermissionError('Invalid credentials')
>>>
>>>
>>> mark = User()
>>>
>>> mark.login(username='mwatney', password='invalid')
Traceback (most recent call last):
PermissionError: Invalid credentials
16.4.7. Catch
Return works the same as in functions
>>> class User:
... def login(self, username, password):
... if not (username == 'mwatney' and password == 'Ares3'):
... raise PermissionError('Invalid credentials')
>>>
>>>
>>> mark = User()
>>>
>>> try:
... mark.login(username='mwatney', password='invalid')
... except PermissionError as e:
... print(f'Authentication error: {e}')
...
Authentication error: Invalid credentials
16.4.8. Use Case - 1
Unrelated functions:
>>> def add(a, b):
... return a + b
>>>
>>> def sub(a, b):
... return a - b
>>>
>>> def mul(a, b):
... return a * b
>>>
>>> def div(a, b):
... return a / b
Class serves as a namespace:
>>> class Calculator:
... def add(self, a, b):
... return a + b
...
... def sub(self, a, b):
... return a - b
...
... def mul(self, a, b):
... return a * b
...
... def div(self, a, b):
... return a / b
16.4.9. Use Case - 2
>>> class Calculator:
... def add(self, a, b):
... return a + b
...
... def sub(self, a, b):
... return a - b
...
... def mul(self, a, b):
... return a * b
...
... def div(self, a, b):
... return a / b
>>>
>>>
>>> calc = Calculator()
>>> calc.add(a=1, b=2)
3
16.4.10. Use Case - 3
Unrelated functions:
>>> def say_hello():
... return 'hello'
>>>
>>> def say_goodbye():
... return 'goodbye'
>>>
>>> def login(username, password):
... return 'User login'
>>>
>>> def logout():
... return 'User logout'
Class serves as a namespace:
>>> class User:
... def say_hello(self):
... return 'hello'
...
... def say_goodbye():
... return 'goodbye'
...
... def login(self, username, password):
... return 'User login'
...
... def logout(self):
... return 'User logout'
16.4.11. Use Case - 4
>>> class List:
... def append(self, item):
... ...
...
... def remove(self, item):
... ...
>>> users = List()
>>>
>>> users.append('mwatney')
>>> users.append('mlewis')
>>> users.append('rmartinez')
>>>
>>> users.remove('rmartinez')
>>> colors = List()
>>>
>>> colors.append('red')
>>> colors.append('green')
>>> colors.append('blue')
>>>
>>> colors.remove('red')
16.4.12. Use Case - 5
>>> class User:
... def login(self, username, password):
... if username == 'mwatney' and password == 'nasa':
... print('ok')
... else:
... raise PermissionError
...
>>>
>>>
>>> mark = User()
>>>
>>> mark.login()
Traceback (most recent call last):
TypeError: User.login() missing 2 required positional arguments: 'username' and 'password'
>>>
>>> mark.login('invalid', 'invalid')
Traceback (most recent call last):
PermissionError
>>>
>>> mark.login('mwatney', 'invalid')
Traceback (most recent call last):
PermissionError
>>>
>>> mark.login('invalid', 'nasa')
Traceback (most recent call last):
PermissionError
>>>
>>> mark.login('mwatney', 'nasa')
ok
>>>
>>> mark.login(username='mwatney', password='nasa')
ok
16.4.13. Assignments
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% About
# - Name: OOP Method One
# - Difficulty: easy
# - Lines: 2
# - Minutes: 2
# %% English
# 1. Modify class `User`
# 2. Define method `login` in class `User`
# 3. Method prints 'User login'
# 3. Run doctests - all must succeed
# %% Polish
# 1. Zmodyfikuj klasę `User`
# 2. Zdefiniuj metodę `login` w klasie `User`
# 3. Metoda wypisuje 'User login'
# 4. Uruchom doctesty - wszystkie muszą się powieść
# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> from inspect import isclass, ismethod
>>> assert isclass(User)
>>> mark = User()
>>> assert ismethod(mark.login)
>>> mark.login()
User login
"""
# Define method `login` in class `User`
# Method prints 'User login'
class User:
...
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% About
# - Name: OOP Method Two
# - Difficulty: easy
# - Lines: 2
# - Minutes: 2
# %% English
# 1. Modify class `User`
# 2. Add new method `logout` in class `User`
# 3. Method prints 'User logout'
# 3. Run doctests - all must succeed
# %% Polish
# 1. Zmodyfikuj klasę `User`
# 2. Dodaj nową metodę `logout` w klasie `User`
# 3. Metoda wypisuje 'User logout'
# 4. Uruchom doctesty - wszystkie muszą się powieść
# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> from inspect import isclass, ismethod
>>> assert isclass(User)
>>> mark = User()
>>> assert ismethod(mark.login)
>>> assert ismethod(mark.logout)
>>> mark.login()
User login
>>> mark.logout()
User logout
"""
# Add new method `logout` in class `User`
# Method prints 'User logout'
class User:
def login(self):
print('User login')
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -v myfile.py`
# %% About
# - Name: OOP Method Parameters
# - Difficulty: easy
# - Lines: 4
# - Minutes: 3
# %% English
# 1. Modify class `User`
# 2. Modify method `login` in class `User`:
# - Method takes `username` and `password` as arguments
# - Method checks if username is 'mwatney' and password is 'Ares3'
# - If true: method prints 'User login'
# - If false: raise PermissionError with 'Invalid username or password'
# 3. Run doctests - all must succeed
# %% Polish
# 1. Zmodyfikuj klasę `User`
# 2. Zmodyfikuj metodę `login` w klasie `User`:
# - Metoda przyjmuje `username` i `password` jako argumenty
# - Metoda sprawdza czy username to 'mwatney' i password to 'Ares3'
# - Jeżeli prawda: metoda wypisuje 'User login'
# - Jeżeli fałsz: rzuć PermissionError z 'Invalid username or password'
# 3. Uruchom doctesty - wszystkie muszą się powieść
# %% Tests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> from inspect import isclass, ismethod
>>> assert isclass(User)
>>> mark = User()
>>> assert ismethod(mark.login)
>>> assert ismethod(mark.logout)
>>> mark.login('mwatney', 'Ares3')
User login
>>> mark.login(username='mwatney', password='Ares3')
User login
>>> mark.login(username='mwatney', password='invalid')
Traceback (most recent call last):
PermissionError: Invalid username or password
>>> mark.login(username='invalid', password='Ares3')
Traceback (most recent call last):
PermissionError: Invalid username or password
>>> mark.login()
Traceback (most recent call last):
TypeError: User.login() missing 2 required positional arguments: 'username' and 'password'
>>> mark.logout()
User logout
"""
# Modify method `login` in class `User`:
# - Method takes `username` and `password` as arguments
# - Method checks if username is 'mwatney' and password is 'Ares3'
# - If true: method prints 'User login'
# - If false: raise PermissionError with 'Invalid username or password'
class User:
def login(self):
print('User login')
def logout(self):
print('User logout')