@@ -11,7 +11,7 @@ complete set of Code Style guidelines and "Pythonic" idioms.
11
11
12
12
On the opposite, when a veteran Python developper (a Pythonistas) point to some
13
13
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
15
15
what is considered the best (hear: most readable) way.
16
16
17
17
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.
79
79
if cond1 and cond2:
80
80
# do something
81
81
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)
82
161
83
162
Avoid the magical wand
84
163
~~~~~~~~~~~~~~~~~~~~~~
0 commit comments