use functools partial instead of self rolled version