1

So lets say I've got a function:

def print_something(a, b, c='something', d='something else'):
    print '{}/{}/{}/{}'.format(a, b, c, d)

And I've got this method:

def print_method(self, a, b):
    if self.c and self.b:
        print_something(a, b, self.c, self.d)
    elif self.c:
        print_something(a, b, c=self.c)
    elif self.d:
        print_something(a, b, d=self.d)
    else:
        print_something(a, b)

Is there a way to get the same functionality as print_method() without having to provide an if for each possible combination of self.c and self.d?

2
  • what are self.c and self.b? Commented Feb 17, 2015 at 22:12
  • They could be many things. Maybe strings that are initially empty but may be appended to. Commented Feb 17, 2015 at 22:16

3 Answers 3

4

You can pass a dictionary to the function call containing keyword argument names and values. So something like this should work:

kwargs = dict((k, getattr(self, k)) for k in ('c', 'd') if getattr(self, k))
print_something(a, b, **kwargs)
Sign up to request clarification or add additional context in comments.

Comments

2

You could change your other function setting values to empty strings so the default will be used unless we get non empty strings passed in:

def print_something(a, b, c="", d=""):
    c = 'something' if not c else c
    d = 'something else' if not d else d
    print('{}/{}/{}/{}'.format(a, b, c, d))

def print_method(self, a, b):
        print_something(a, b, self.c, self.d)

Or more concisely as you consider any falsey value to be false in the if checks in your class we can use c = c or default

def print_something(a, b, c="", d=""):
    c = c or 'something' 
    d = d or 'something else' 
    print('{}/{}/{}/{}'.format(a, b, c, d))

4 Comments

i always like the the more concise c = c or 'something' formulation.
@acushner, yes I have a bit of a mental block when it comes to using that but yes it will work , I will add it
I feel the x if x else y construct is more idiomatic.
@AndrewGorcester, I feel more comfortable using it too but I suppose in this case they are equivalent as we are not checking ` if x is not None` etc..
-1

You could use **args here:

def print_method(self, a, b):
    extra_args = {}
    if self.c:
        extra_args['c'] = self.c
    if self.d:
        extra_args['d'] = self.d
    print_something(a, b, **extra_args)

This calls print_something() with however many extra arguments you have.

1 Comment

This won't do the right thing. Because if self.d is set, but self.c is not, positionally, c will be assigned self.d, which seems counter to what the questioner desires.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.