Photo by Christina Morillo: https://www.pexels.com/photo/woman-programming-on-a-notebook-1181359/

Callables and functions in Python: a simple explanation with an example

Jonathan Serrano
5 min readMay 14, 2022

--

When I read the book Bayesian Methods for Hackers I found many times code like this.

N = rfm_cal_holdout.shape[0] 
x = rfm_cal_holdout['frequency_cal'].values
t_x = rfm_cal_holdout['recency_cal'].values
T = rfm_cal_holdout['T_cal'].values
bgnbd_model = pm.Model()
with bgnbd_model:
def logp(x, t_x, T):
"""
Loglikelihood function
"""
# Bla bla
# Some fancy stuff that calculates the value of A3
return A3
# This is the important part --------------------|
# v
loglikelihood = pm.DensityDist("loglikelihood", logp, observed= {'x': x, 't_x': t_x, 'T': T})

I knew that functions were treated as first-class objects by Python, nevertheless, I was a bit confused when I read this piece of code. The questions that came to my mind were like.

  • Why is `pm.DensityDist` receiving logp as a parameter?
  • Where are logp parameters?
  • How in the world variables x, t_x, and T are passed so that logp resolves to a value? Is it because they are declared above and somehow “are passed” into logp function instance?
  • Why is this thing working in…

--

--

Jonathan Serrano

Tech advocate, developer, ML enthusiast and PhD in Computer Science.