2.6. Callable

2.6.1. First-class Function

  • If a function can be assigned to a variable or passed as object/variable to other function.

  • Can be used as parameters

  • Can be used as a return value

  • Can be assigned to variables

  • Can be stored in data structures such as hash tables, lists, ...

def lower():
    return 'My name... José Jiménez'

def higher():
    return lower


text = higher()     # <function __main__.lower()>
text()              # 'My name... José Jiménez'

2.6.2. Aliases

import datetime
import time


now = datetime.datetime.now()

print(now)            # 1969-07-21 02:56:15
time.sleep(10)
print(now)            # 1969-07-21 02:56:15
import datetime
import time


now = datetime.datetime.now

print(now())          # 1969-07-21 02:56:15
time.sleep(10)
print(now())          # 1969-07-21 02:56:25
import datetime
import time


now = datetime.datetime.now

print(now())
# 1969-07-21 02:56:25

print(now)
# <built-in method now of type object at 0x107695638>

now()
# datetime.datetime(1969, 7, 21, 2, 56, 25)

now.__call__()
# datetime.datetime(1969, 7, 21, 2, 56, 25)

2.6.3. Callable

  • __call__() method makes object callable

def hello():
    return 'My name... José Jiménez'


type(hello())         # <class 'str'>
hello()               # My name... José Jiménez

type(hello)           # <class 'function'>
hello                 # <function hello at 0x0C55D420>
astro = str('Mark Watney')

type(astro)
# <class 'str'>

astro()
# TypeError: 'str' object is not callable
class str(str):
    def __call__(self):
        print('hello')


astro = str('Mark Watney')

type(astro)
# <class '__main__.str'>

astro()
# hello

2.6.4. Callbacks

Listing 2.123. Callback Design Pattern
from http import HTTPStatus
import requests


def noop(*arg, **kwargs):
    pass


def http_request(url, on_success=noop, on_error=noop):
    result = requests.get(url)
    if result.status_code == HTTPStatus.OK:
        on_success(result)
    else:
        on_error(result)


def success(result):
    print('Success')


def error(result):
    print('Error')


http_request(
    url='http://python.astrotech.io',
    on_success=success,
    on_error=error,
)

2.6.5. Type Annotation

from typing import Callable

def http_request(url: str,
                 on_success: Callable = noop,
                 on_error: Callable = noop) -> None:
    pass
from typing import Callable


def lower() -> str:
    return 'My name... José Jiménez'

def higher() -> Callable:
    return lower


text = higher()     # <function __main__.lower()>
text()              # 'My name... José Jiménez'

2.6.6. Assignments

2.6.6.1. Function First Class Check

English
  1. Define function wrapper

  2. wrapper takes *args and **kwargs as arguments

  3. Define function check which takes func: Callable as an argument

  4. Function check must return wrapper: Callable

Polish
  1. Zdefiniuj funkcję wrapper

  2. wrapper przyjmuje *args i **kwargs jako argumenty

  3. Zdefiniuj funkcję check, która przyjmuje func: Callable jako argument

  4. Funkcja check ma zwracać wrapper: Callable