Skip to content

Commit 57e7366

Browse files
author
Kenneth Reitz
committed
Merge pull request #151 from guibog/master
Add a block about function arguments
2 parents 32afdb9 + 7cec41a commit 57e7366

File tree

1 file changed

+80
-1
lines changed

1 file changed

+80
-1
lines changed

docs/writing/style.rst

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ complete set of Code Style guidelines and "Pythonic" idioms.
1111

1212
On the opposite, when a veteran Python developper (a Pythonistas) point to some
1313
parts of a code and say it is not "Pythonic", it usually means that these lines
14-
of code do not follow the common guidelines and fail to express the intent is
14+
of code do not follow the common guidelines and fail to express the intent in
1515
what is considered the best (hear: most readable) way.
1616

1717
On some border cases, no best way has been agreed upon on how to express
@@ -79,6 +79,85 @@ it is bad practice to have two disjoint statements on the same line.
7979
if cond1 and cond2:
8080
# do something
8181
82+
Function arguments
83+
~~~~~~~~~~~~~~~~~~
84+
85+
Arguments can be passed to functions in four different ways.
86+
87+
**Positional arguments** are mandatory and have no default values. They are the
88+
simplest form of arguments and they can be used for the few function arguments
89+
that are fully part of the functions meaning and their order is natural. For
90+
instance, in ``send(message, recipient)`` or ``point(x, y)`` the user of the
91+
function has no difficulty to remember that those two function require two
92+
arguments, and in which order.
93+
94+
In those two cases, it is possible to use argument names when calling the functions
95+
and, doing so, it is possible to switch the order of arguments, calling for instance
96+
``send(recipient='World', message='Hello')`` and ``point(y=2, x=1)`` but this
97+
reduce readability and is unnecessarily verbose, compared to the more straightforward
98+
calls to ``send('Hello', 'World')`` and ``point(1, 2)``.
99+
100+
**Keyword arguments** are not mandatory and have default values. They are often
101+
used for optional parameters sent to the function. When a function has more than
102+
two or three positional parameters, its signature will be more difficult to remember
103+
and using keyword argument with default values is helpful. For instance, a more
104+
complete ``send`` function could be defined as ``send(message, to, cc=None, bcc=None)``.
105+
Here ``cc`` and ``bcc`` are optional, and evaluate to ``None`` when the are not
106+
passed another value.
107+
108+
Calling a function with keyword arguments can be done in multiple ways in Python,
109+
for example it is possible to follow the order of arguments in the definition without
110+
explicitely naming the arguments, like in ``send('Hello', 'World', 'Cthulhu`, 'God')``,
111+
sending a blank carbon copy to God. It would also be possible to name arguments in
112+
another order, like in ``send('Hello again', 'World', bcc='God', cc='Cthulhu')``.
113+
Those two possibilities are better avoided whitout any strong reason to not
114+
follow the syntax that is the closest to the function definition: ``send('Hello',
115+
'World', cc='Cthulhu', bcc='God')``.
116+
117+
As a side note, following YAGNI_ principle, it is often harder to remove an
118+
optional argument (and its logic inside the function) that was added "just in
119+
case" and is seemingly never used, than to add a new optional argument and its
120+
logic when needed.
121+
122+
The **arbitrary argument list** is the third way to pass arguments to a
123+
function. If the function intention is better expressed by a signature with an
124+
extensible number of positional arguments, it can be defined with the ``*args``
125+
constructs. In the function body, ``args`` will be a tuple of all the
126+
remaining positional arguments. For example, ``send(message, *args)`` can be
127+
called with each recipient as an argument: ``send('Hello', 'God', 'Mom',
128+
'Cthulhu')``, and in the function body ``args`` will be equal to ``('God',
129+
'Mom', 'Cthulhu')``.
130+
131+
However, this construct has some drawback and should be used with caution. If a
132+
function receives a list of arguments of the same nature, it is often more
133+
clear to define it as a function of one argument, that argument being a list or
134+
any sequence. Here, if ``send`` has multiple recipients, it is better to define
135+
it explicitely: ``send(message, recipients)`` and call it with ``send('Hello',
136+
['God', 'Mom', 'Cthulhu'])``. This way, the user of the function can manipulate
137+
the recipient list as a list beforhand, and it opens the possibility to pass
138+
any sequence, inculding iterators, that cannot be unpacked as other sequences.
139+
140+
The **arbitrary keyword argument dictionary** is the last way to pass arguments
141+
to functions. If the function requires an undetermined serie of named
142+
arguments, it is possible to used the ``**kwargs`` construct. In the function
143+
body, ``kwargs`` will be a dictionary of all the passed named arguments that
144+
have not been caught be other keyword argument in the function signature.
145+
146+
The same caution as in the case of *arbitrary argument list* is necessary, for
147+
similar reasons: these powerful techniques are to be used when there is a
148+
proven necessity to use them, and they should not be used if the simpler and
149+
clearer construct is sufficient to express the function's intention.
150+
151+
It is up to the programmer writing the function to determine which arguments
152+
are positional argmuents and which are optional keyword arguments, and to
153+
decide wheter to use the advanced techniques of arbitrary argument passing. If
154+
the advices above are followed wisely, it is possible and enjoyable to write
155+
Python functions that are:
156+
157+
* easy to read (the name and arguments need no explanations)
158+
159+
* easy to change (adding a new keyword argument do not break other parts of the
160+
code)
82161
83162
Avoid the magical wand
84163
~~~~~~~~~~~~~~~~~~~~~~

0 commit comments

Comments
 (0)