6

I found many queries on python function arguments but still left confused. Suppose I want to pass few arguments in some function.

def anyFunc(name, age, sex = 'M', *cap_letters ):
    print "name ", name
    print "age ", age
    print "sex ", sex
    for s in cap_letters:
        print "capital letter: ", s

name & age arguments are positional arguments. sex is default argument followed by variable length of non keyword arguments which are few random capital alphabets. So now if I run

anyFunc("Mona", 45, 'F', *('H', 'K', 'L'))

It gives me perfect output..

name  Mona
age  45
sex  F
capital letter:  H
capital letter:  K
capital letter:  L

But if I pass below arguments where I want to use default sex value instead of passing it. Output is not as expeceted.

anyFunc("John", 45, *('H', 'K', 'L'))

name  John
age  45
sex  H
capital letter:  K
capital letter:  L

It should have taken the default value of sex i.e. 'M'. I also tried to pass sex argument at the very last but it gave me syntax error. Is there any way to achieve what I want?

1
  • I Python ≥ 3.0, you could make sex a keyword-only argument. In Python 2.x you don't have that option, though. Commented Jan 22, 2016 at 20:46

2 Answers 2

2

Don't use * magic in a functions signature if you also use/need it on the calling side. Then simply drop it on both sides and don't make it more complicated as it has to be:

def any_func(name, age, sex='M', capital_letters=()):
    print 'name ', name
    print 'age ', age
    print 'sex ', sex
    for capital_letter in capital_letters:
        print 'capital letter: ', capital_letter

Called as:

any_func('Mona', 45, 'F', ('H', 'K', 'L'))

And with default sex:

any_func('John', 45, capital_letters=('H', 'K', 'L'))

If you don't like spelling out the capital_letters arguments name at many calls and it is acceptable to reorder the arguments, then swap the last two arguments:

def any_func(name, age, capital_letters=(), sex='M'):
    print 'name ', name
    print 'age ', age
    print 'sex ', sex
    for capital_letter in capital_letters:
        print 'capital letter: ', capital_letter

Calls:

any_func('Mona', 45, ('H', 'K', 'L'), 'F')
any_func('John', 45, ('H', 'K', 'L'))
Sign up to request clarification or add additional context in comments.

Comments

1

make sex a **kwargs in your function. Inside your function, check whether user has passed sex as key argument or not. If user hasn't passed anything than continue with default value of sex.

your function will look like this:

def anyFunc(name, age, *cap_letters,**sexKwarg): print "name ", name print "age ", age sex = sexKwarg.get('sex', 'M') print "sex ", sex for s in cap_letters: print "capital letter: ", s Usage: anyFunc("Mona", 45, *('H', 'K', 'L'), sex = 'F') anyFunc("Mona", 45, *('H', 'K', 'L')) ##use default sex

4 Comments

I have updated my answer and has posted a complete solution. Accept my answer if this helps
kwargs is a dictionary so iterating through it to get the value for a key is insane. Just do sex = kwargs.get('sex', 'M').
This has the disadvantage of hiding the sex argument from the function signature.
@BlackJack Thank you for feedback. You are absolutely right. I have incorporated your two comments in my updated answer.

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.