49
amitu.com Function arguments: positional and keyword Excerpt from Python For Programmers

Function arguments In Python

Embed Size (px)

Citation preview

Page 1: Function arguments In Python

amitu.com

Function arguments: positional and keyword

Excerpt from Python For Programmers

Page 2: Function arguments In Python

amitu.com Descriptors In Python

This is from a section in my “Python for Developers” book. The book covers python

material for people who are already developers, even python developers.

Check it out: amitu.com/python/

Page 3: Function arguments In Python

amitu.com Descriptors In Python

In this we are going to learn about function arguments in Python

Positional and Keyword arguments, * and ** syntax etc.

Page 4: Function arguments In Python

amitu.com Function arguments: positional and keyword

Functions can take arguments when called.

Here we have defined a function foo, that takes a single “positional argument”, x.

When we called foo(12), 12 got assigned to x when the control was inside foo().

Page 5: Function arguments In Python

amitu.com Function arguments: positional and keyword

We can have more than one arguments:

So far so good.

Page 6: Function arguments In Python

amitu.com Function arguments: positional and keyword

One problem with function taking many arguments is remembering the order of arguments.

Page 7: Function arguments In Python

amitu.com Function arguments: positional and keyword

Knowing that a function add_user() exists is not enough, nor is knowing that it takes name, gender

and location. You must also remember in what order those three must be supplied.

How do we make such obviously wrong code look wrong?

Page 8: Function arguments In Python

amitu.com Function arguments: positional and keyword

Sometimes your code editor can help you. But we can not always rely on that. What if you are

browsing code on GitHub?

Page 9: Function arguments In Python

amitu.com Function arguments: positional and keyword

To solve this precise problem, Python supports function calling using what is called

“keyword argument” syntax:

… as against “positional arguments”, eg foo(10, 20), where arguments are identified by

their position.

Page 10: Function arguments In Python

amitu.com Function arguments: positional and keyword

When using keyword arguments, you can even change the order of keyword arguments, and

python will do the right thing.

Page 11: Function arguments In Python

amitu.com Function arguments: positional and keyword

We can also mix both positional and keyword arguments:

isn't Python cool?

Page 12: Function arguments In Python

amitu.com Function arguments: positional and keyword

There is one constraint—we can not pass a positional argument after a keyword argument. If we use both, all positional arguments must come before

any keyword argument.

Page 13: Function arguments In Python

amitu.com Function arguments: positional and keyword

Default ValuesNext:

Page 14: Function arguments In Python

amitu.com Function arguments: positional and keyword

In Python, we can define functions with arguments that take default values.

Page 15: Function arguments In Python

amitu.com Function arguments: positional and keyword

We defined foo() to have default value of 10 for y. If we don't pass anything for y,

python uses the default value.

Page 16: Function arguments In Python

amitu.com Function arguments: positional and keyword

Only y has a default value, x is still a required argument.

Page 17: Function arguments In Python

amitu.com Function arguments: positional and keyword

We can still use keyword arguments:

Or a mixed arguments:

Page 18: Function arguments In Python

amitu.com Function arguments: positional and keyword

NOTE: like we can not pass keyword arguments after positional arguments when calling function, we

similarly cannot define functions with default values before arguments that do not have default values.

Arguments with default values must come at the end.

Page 19: Function arguments In Python

amitu.com Function arguments: positional and keyword

Mutable default value gotcha

Page 20: Function arguments In Python

amitu.com Function arguments: positional and keyword

One common gotcha when using default arguments is using a mutable type as the default value.

Default value for users here is a list, [ ], which is a mutable data type in Python.

Page 21: Function arguments In Python

amitu.com Function arguments: positional and keyword

Let us say our intention is to create a users list. If it is not passed we want to use an empty list by default. We

append to passed list, or the default empty list, and returned the modified list.

Page 22: Function arguments In Python

amitu.com Function arguments: positional and keyword

So far, so good, and it seems to be working fine. Let us see when and where the problem begins.

What happened here? Why is “sam” in the free_users list? add_user() should have taken

default empty list, and added “richard” and returned that. Why two members?

Page 23: Function arguments In Python

amitu.com Function arguments: positional and keyword

What is happening is that, the empty list we have used as default value of users in the function definition…

… the same instance is used as value of users, every time we do not pass the second parameter.

And by the second time function is called, the list is not empty any more!

Page 24: Function arguments In Python

amitu.com Function arguments: positional and keyword

The proper way to write such a function would be using a value that would never make sense

to be passed, say None or -1.

ASIDE: such use of a value that is used for a special purpose is called a sentinel value.

Page 25: Function arguments In Python

amitu.com Function arguments: positional and keyword

There is another subtle mistake we can make. Let us look at another version of add_user() to

give emphasis to it.

Here, we first check if the passed in value is None. We have used strong identity check (is None).

Page 26: Function arguments In Python

amitu.com Function arguments: positional and keyword

The difference is subtle users is None vs not users.

First creates a new list if nothing was passed (and we took the default value of None), other if empty list was passed.

Page 27: Function arguments In Python

amitu.com Function arguments: positional and keyword

Yet another more reliable way to create sentinel values is:

Page 28: Function arguments In Python

amitu.com Function arguments: positional and keyword

The reason such NotPassed is preferable over None is because our code can have None assigned to something by mistake, but getting NotPassed

assigned to some variable has to be intentional.

Page 29: Function arguments In Python

amitu.com Function arguments: positional and keyword

Variable ArgumentsSometimes we want to write functions that

take variable number of arguments.

Page 30: Function arguments In Python

amitu.com Function arguments: positional and keyword

This is how we write a function in Python that takes variable number of arguments:

Page 31: Function arguments In Python

amitu.com Function arguments: positional and keyword

Note the *args. The * indicates to Python that this function takes the variable number

of positional arguments, and when the function is called, all those arguments are

stored in tuple() and passed to the function by the name args. Instead of args, we could

have called it anything.

Page 32: Function arguments In Python

amitu.com Function arguments: positional and keyword

We can not treat args as a keyword argument.

But we can achieve the same by * syntax:

Page 33: Function arguments In Python

amitu.com Function arguments: positional and keyword

We have used * while calling the function. When using this syntax, we must pass an iterable. It

can be a tuple, a list, or any iterable.

Note that the list was converted to a tuple. Whatever you pass will get converted to tuple.

Page 34: Function arguments In Python

amitu.com Function arguments: positional and keyword

We can use this syntax even for functions that do not take a variable number of arguments…

Page 35: Function arguments In Python

amitu.com Function arguments: positional and keyword

… as long as the number of items we pass is correct.

Page 36: Function arguments In Python

amitu.com Function arguments: positional and keyword

You can also mix variable arguments with positional arguments.

Page 37: Function arguments In Python

amitu.com Function arguments: positional and keyword

Remember that we can not pass positional arguments after keyword arguments.

Page 38: Function arguments In Python

amitu.com Function arguments: positional and keyword

In Python 2, this would not be valid:

Page 39: Function arguments In Python

amitu.com Function arguments: positional and keyword

Python 3 accepts it, but treats y as a compulsory keyword argument.

Page 40: Function arguments In Python

amitu.com Function arguments: positional and keyword

A variable number of arguments works with default value arguments too.

… both in Python 2 and Python 3.

Page 41: Function arguments In Python

amitu.com Function arguments: positional and keyword

But there is a possibility of ambiguity here.

Python would not accept it.

Page 42: Function arguments In Python

amitu.com Function arguments: positional and keyword

Like we have *arg syntax which tells Python to capture all remaining positional arguments,

there is a similar **kw syntax that tells Python to capture all remaining keyword arguments

even ones we never defined.

Page 43: Function arguments In Python

amitu.com Function arguments: positional and keyword

Python will capture all the keyword arguments in a dict(), so everything that we know about dict() can be used with them.

Page 44: Function arguments In Python

amitu.com Function arguments: positional and keyword

A new dictionary is constructed for you every time a function that takes variable number of

keyword arguments is called.

Page 45: Function arguments In Python

amitu.com Function arguments: positional and keyword

In this case, our function accepts no positional argument, so we can not call it

with a positional argument.

Page 46: Function arguments In Python

amitu.com Function arguments: positional and keyword

You can mix and match all forms of arguments in a single function.

Just be careful that keyword arguments must come after positional ones, and there must not be any ambiguities.

Page 47: Function arguments In Python

amitu.com Function arguments: positional and keyword

Finally, you can use the **{} syntax when calling a function too.

Even when the function being called doesn't take keyword arguments…

Page 48: Function arguments In Python

amitu.com Function arguments: positional and keyword

With these features, we can create a "universal function" that can be called with any combination of

positional and keyword arguments:

These play special role when we are writing generic decorators, or when we want to override a method

without knowing the parent methods signature.

Page 49: Function arguments In Python

amitu.com Descriptors In Python

Thats it for now!

You have seen a section in my “Python for Developers” book. The book covers

python material for people who're already developers, even python developers.

Check it out: amitu.com/python/