0

Ok I am not even sure the proper terminology to use to describe what I am trying to do. Anyway, I want to know if it is possible to programmatically or dynamically build a function call in python.

Let me explain.

I have a function inside a class that is defined with optional parameters like so:

    class Agents(object):

        def update(self, agent_id, full_name = "none", role = "none", status = "none"):
            # do some stuff

So when I when I go to use that function, I may be updating just one, two or all 3 of the optional parameters. Sometimes it may be full_name and role but not status... or status and role but not name, or just status, or well you get the idea.

So I could handle this with a big block of if elif statements to account for all the permutations but that strikes me as really clumsy.

Currently I am calling the function like so:

    an_agent = Agents()
    an_agent.update(agent_id = r_agent_id)

Is there anyway to construct that function call programmatically, like appending the arguments to the call before making it. So that I can account for multiple scenarios like so:

    an_agent = Agents()
    an_agent.update(agent_id = r_agent_id, full_name = r_full_name)

or

    an_agent = Agents()
    an_agent.update(agent_id = r_agent_id, full_name = r_full_name, status = r_status)

Anyway, what is the best way to approach this?

davidism
  • 121,510
  • 29
  • 395
  • 339
JOG88
  • 51
  • 1
  • 9

1 Answers1

1

If I understand correctly, I think this is what you're looking for:

params = {}

if x:
    params['full_name'] = 'something'
if y:
    params['role'] = 'something else'

an_agent.update(r_agent_id, **params)

UPDATE

There are other options, assuming you control the code for Agents. E.g., you could redefine the method like this:

def update(self, agent_id, full_name=None, role=None, status=None):
    if full_name is None: full_name = 'none'
    if role is None: role = 'none'
    if status is None: status = 'none'
    ...

and then always pass all arguments:

full_name = None
role = None
status = None

if x:
    full_name = 'something'
if y:
    role = 'something else'

an_agent.update(r_agent_id, full_name, role, status)

or perhaps keep the definition of update the same and just initialize your parameters to the string 'none'.

user94559
  • 59,196
  • 6
  • 103
  • 103
  • I just want to add that the `**` syntax can be googled using the commonly associated word `**kwargs`. Here are also some SO answers on how it works : [1](http://stackoverflow.com/a/1769475/5847976) [2](http://stackoverflow.com/a/3394898/5847976) [3](http://stackoverflow.com/a/36908/5847976) – jadsq Aug 16 '16 at 15:06
  • Ok awesome, let me digest this and give it a go. I might have a couple follow up questions. Thanks man this is great! – JOG88 Aug 16 '16 at 15:09
  • 1
    Yep, **kwargs was the solution for sure. By implementing that across several of my functions I was able to eliminate huge chunks of unnecessary if statements. Code is so much cleaner now. Thanks man, marking the answer. – JOG88 Aug 16 '16 at 17:04