Function arguments In Python
-
Upload
amit-upadhyay -
Category
Technology
-
view
189 -
download
0
Transcript of Function arguments In Python
amitu.com
Function arguments: positional and keyword
Excerpt from Python For Programmers
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/
amitu.com Descriptors In Python
In this we are going to learn about function arguments in Python
Positional and Keyword arguments, * and ** syntax etc.
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().
amitu.com Function arguments: positional and keyword
We can have more than one arguments:
So far so good.
amitu.com Function arguments: positional and keyword
One problem with function taking many arguments is remembering the order of arguments.
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?
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?
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.
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.
amitu.com Function arguments: positional and keyword
We can also mix both positional and keyword arguments:
isn't Python cool?
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.
amitu.com Function arguments: positional and keyword
Default ValuesNext:
amitu.com Function arguments: positional and keyword
In Python, we can define functions with arguments that take default values.
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.
amitu.com Function arguments: positional and keyword
Only y has a default value, x is still a required argument.
amitu.com Function arguments: positional and keyword
We can still use keyword arguments:
Or a mixed arguments:
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.
amitu.com Function arguments: positional and keyword
Mutable default value gotcha
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.
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.
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?
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!
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.
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).
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.
amitu.com Function arguments: positional and keyword
Yet another more reliable way to create sentinel values is:
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.
amitu.com Function arguments: positional and keyword
Variable ArgumentsSometimes we want to write functions that
take variable number of arguments.
amitu.com Function arguments: positional and keyword
This is how we write a function in Python that takes variable number of arguments:
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.
amitu.com Function arguments: positional and keyword
We can not treat args as a keyword argument.
But we can achieve the same by * syntax:
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.
amitu.com Function arguments: positional and keyword
We can use this syntax even for functions that do not take a variable number of arguments…
amitu.com Function arguments: positional and keyword
… as long as the number of items we pass is correct.
amitu.com Function arguments: positional and keyword
You can also mix variable arguments with positional arguments.
amitu.com Function arguments: positional and keyword
Remember that we can not pass positional arguments after keyword arguments.
amitu.com Function arguments: positional and keyword
In Python 2, this would not be valid:
amitu.com Function arguments: positional and keyword
Python 3 accepts it, but treats y as a compulsory keyword argument.
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.
amitu.com Function arguments: positional and keyword
But there is a possibility of ambiguity here.
Python would not accept it.
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.
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.
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.
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.
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.
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…
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.
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/