11

especially when there are so many parameters (10+ 20+).

What are good ways of enforcing required/optional parameters to a function?

What are some good books that deal with this kind of questions for python?
(like effective c++ for c++)

** EDIT **

I think it's very unpractical to list def foo(self, arg1, arg2, arg3, .. arg20, .....): when there are so many required parameters.

eugene
  • 39,839
  • 68
  • 255
  • 489
  • 2
    http://stackoverflow.com/questions/14017996/python-optional-parameter Does this help? – Mudit Gupta Jul 14 '16 at 01:37
  • a good resource for python even if you are not learning to program is http://learnpythonthehardway.org/book/ – GMarsh Jul 14 '16 at 01:40
  • 2
    Having a large number of arguments in a function is a good indicator you should refactor your code, probably breaking it into multiple functions. – Kal Zekdor Jul 14 '16 at 01:48
  • Generally speaking for most programming languages, if your function has > 5 parameters your code starts to get bad code smell. > 10 has really really bad code smell and would force me to question the entire project's design and/or the author. But there are always exceptions. (I have worked with code that took 10 or so parameters everyone agreed it was bad... a temporary band aid was to put the parameters into a struct). – Trevor Boyd Smith Jul 14 '16 at 01:53
  • Suppose you are creating an `importer` that imports product data from excel sheet. It goes over +10 easily. How do you suppose to break them? – eugene Jul 14 '16 at 02:27

4 Answers4

14

Parameters can be required or optional depending on how they appear in the function definition:

def myfunction(p1, p2, p3=False, p4=5)

In this definition, parameters p1 and p2 are required. p3 is optional and will acquire the value False if not provided by the caller. p4 is also optional and will acquire the value 5 if not provided.

If you really need to pass ten or more parameters into a function, it might be better to pass them as a dictionary:

args = {'a': something, 'b': something_else, 'c': 5, 'd': 99.99, ... }
myfunc(args)
John Gordon
  • 29,573
  • 7
  • 33
  • 58
  • 3
    Not sure I agree with the last comment, passing something as a `dict` if there are a number of (variable) args, this would make understanding code much harder and more error prone. I would use `*args` or `**kwargs`, then you can then mix required and optional. – AChampion Jul 14 '16 at 01:52
3

If a function parameter is not required, you can set it equal to None.

def hello(first_name, last_name=None):
    print "Hello " + first_name

Or as John Gordon said, you can set a parameter with a default value the same way.

Note that optional parameters need to be defined after the required parameters.

GMarsh
  • 2,401
  • 3
  • 13
  • 22
3

You can denote required keyword argument as follows:

def myfunc(positional_arg, *, required_kwarg, optional_kwarg=None, **other_kwargs):
  pass
John Jiang
  • 827
  • 1
  • 9
  • 19
2

One way is to have your required parameters be named like func(a, b, c=1) and this would denote required because the code will error out at runtime if missing any. Then for the optional parameters you would then use Python's args and kwargs.

Of course anytime you use Python's args and kwargs means additional code to pull the parameter from the args and kwargs.

Additionally for each combination of optional parameters you then would need to code a bunch of conditional control flow.

In addition you don't want too many optional assignments because it makes the code's API to complex to describe... and the control flow have to many lines of code because the number of possible combinations grows very quickly for each additional optional parameter.

AND your test code grows EVEN faster...

Trevor Boyd Smith
  • 18,164
  • 32
  • 127
  • 177
  • Also... the big difference between compiled languages and interpreted when it comes to required vs optional parameters is if you forget a required parameter... you only find that bug at runtime. Ex: a function with parameters x and y, if you forget parameter y then you only get the error at runtime. – Trevor Boyd Smith Jul 14 '16 at 02:10