September 30, 2017

using functoools to generate new functions from existing ones!

Lets start with a very basic example which demonstrates why we might need functools.partial in the first place, then we will look into a more concrete example.

we have a power function which is used to compute powers obviously ;)

def power(base, exponent):
    return base ** power

>>> power(2,3)
8
>>> power(3,3)
27

Now suppose we want to introduce some custome functions which make use of power function

def square(base):
    return power(base,2)

def cube(base):
    return power(base,3)

# and lots more similar function definations

In all the above cases we can see that the new function is generated by utillising the older funciton by just pre-determining one argument. in case of square() 2 is fixed while in case of cube() 3 is fixed.

Can we can do something better to achieve the same functionality as above? Yes!

lets see how.

def power(base, exponent):
    return base ** power


square = functools.partial(power, exp=2)
cube = functools.partial(power,exp=3)


>>> print square(5)
25
>>> print cube(1)
1

using functools.partial we were able to create new functions from existing one! :)

another example refrence

def _send_email(to, subject, body):
  send_mail(
    subject,
    body,
    settings.EMAIL_HOST_USER,
  )


email_admin      = partial(_send_email, to="admin@example.com")
email_general_it = partial(_send_email, to="it@example.com")
email_marketing  = partial(_send_email, to="marketing@example.com")
email_sales      = partial(_send_email, to="sales@example.com")

...

if thing_is_broken():
  # the 'to' field is already filled in! Hooray!
  email_admin(subject="It's brokened!", body='Fix it!')


if sales_people(): 
  email_sales(subject="sales stuff", body="business, business, business!")