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 parameter

  • At 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 parameter

  • Later 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')