You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Arguments can be positional or keyword if neither the `/` nor `*` operators are used in the parameter definitions.
139
131
Alternately, the positional-or-keyword arguments can be placed between the positional-only parameters on the left and the keyword-only parameters on the right.
140
132
141
-
Following is an example of positional-only, positional-or-keyword, and keyword-only arguments:
133
+
Positional-only, positional-or-keyword, and keyword-only arguments:
142
134
143
135
```python
144
136
# Position-only argument followed by position-or-keyword, followed by keyword-only.
TypeError: concat() got some positional-only arguments passed as keyword arguments: 'greeting'
157
-
158
150
```
159
151
160
152
## `*args`
@@ -164,7 +156,6 @@ Code examples will often use a function definition something like the following:
164
156
```python
165
157
defmy_function(*args, **kwargs):
166
158
# code snipped
167
-
168
159
```
169
160
170
161
`*args` is a two-part name that represents a `tuple` with an indefinite number of separate positional arguments, also known as a [`variadic argument`][variadic argument].
@@ -175,77 +166,77 @@ The `*` is the operator which transforms the group of separate arguments into a
175
166
If you have ever [unpacked a tuple][unpack a tuple] you may find the `*` in `*args` to be confusing.
176
167
The `*` in a _parameter_ definition, instead of unpacking a tuple, converts one or more positional arguments _into_ a tuple.
177
168
178
-
We say that the `*` operator is [overloaded], as it has different behavior in different contexts.
169
+
We say that the `*` operator is [_overloaded_][overloading], as it has different behavior in different contexts.
179
170
For instance, `*` is used for multiplication, it is used for unpacking, and it is used to define an arbitrary number of positional parameters.
Since a tuple can be iterated, `args` can be passed to any other function which takes an iterable.
176
+
Since a tuple can be iterated over, `args` can be passed to any other function which takes an iterable.
183
177
Although `*args` is commonly juxtaposed with `**kwargs`, it doesn't have to be.
184
178
185
-
Following is an example of an arbitrary number of values being passed to a function:
179
+
An arbitrary number of values being passed to a function:
186
180
187
181
```python
188
-
189
182
>>>defadd(*args):
190
-
# args is passed to the sum function, which takes an iterable
191
-
...returnsum(args)
192
-
...
183
+
# args is passed to the sum function, which iterates over it.
184
+
...returnsum(args)
185
+
193
186
>>>print(add(1, 2, 3))
194
187
6
195
188
```
196
189
197
190
If `*args` follows one or more positional arguments, then `*args` will be what is left over after the positional arguments.
198
191
199
-
Following is an example of an arbitrary number of values being passed to a function after a positional argument:
192
+
An arbitrary number of values being passed to a function after a positional argument:
200
193
201
194
```python
202
-
203
195
>>>defadd(first, *args):
204
196
# first will be 1, leaving the values 2 and 3 in *args
205
197
...return first +sum(args)
206
-
...
198
+
207
199
>>>print(add(1, 2, 3))
208
200
6
209
201
```
210
202
211
-
If one or more default argumentsare defined after `*args` they are separate from the `*args` values.
203
+
If one or more [default arguments][default arguments]are defined after `*args`, they are separate from the `*args` values.
212
204
213
-
To put it all together is an example of an arbitrary number of values being passed to a function that also has a positional argument and a default argument:
205
+
To put it all together:
214
206
215
207
```python
216
208
217
209
>>>defadd(first, *args, last=0):
218
-
...return first +sum(args) + last
219
-
...
210
+
...return first +sum(args) + last
211
+
220
212
>>>print(add(1, 2, 3))
221
213
6
222
214
>>>print(add(1, 2, 3, last=4))
223
215
10
216
+
224
217
# This uses the unpacking operator * to separate the list elements into positional arguments.
225
-
# It does not have the same behavior as the * in *args.
218
+
# It does not have the same behavior as the * (packing) in *args.
226
219
>>>print(add(*[1, 2, 3]))
227
220
6
228
-
229
221
```
230
222
231
-
Note that when an argument is already in an iterable, such as a tuple or list, it needs to be unpacked before being passed to a function that takes an arbitrary number of separate arguments.
223
+
Note that when an argument is already inside an `iterable`, such as a `tuple` or `list`, it needs to be [_unpacked_][unpacking-and-multiple-assignment] before being passed to a function that takes an arbitrary number of separate arguments.
232
224
This is accomplished by using `*`, which is the [unpacking operator][unpacking operator].
233
225
234
226
`*` in this context _unpacks_ the container into its separate elements which are then transformed by `*args` into a tuple.
235
-
Where there are only positional arguments, the unpacking action must result in the same number of arguments as there are formal parameters.
227
+
Where there are only positional arguments, the unpacking action must result in the same number of arguments as there are formal parameters defined.
236
228
237
229
Without unpacking the list passed into `add`, the program would error.
238
230
239
231
```python
240
-
>>>>defadd(first, *args, last=0):
241
-
...return first +sum(args) + last
242
-
...
243
-
>>>>print(add([1, 2, 3]))
232
+
>>>defadd(first, *args, last=0):
233
+
...return first +sum(args) + last
234
+
235
+
>>>print(add([1, 2, 3]))
244
236
Traceback (most recent call last):
245
237
print(add([1, 2, 3]))
246
238
return first +sum(args) + last
247
239
TypeError: can only concatenate list (not"int") to list
248
-
249
240
```
250
241
251
242
## `**kwargs`
@@ -254,42 +245,37 @@ TypeError: can only concatenate list (not "int") to list
254
245
`kwargs` is the name of the group of arguments and could be any other name, such as `my_args`, `arguments`, etc.
255
246
The `**` transforms the group of named arguments into a [`dictionary`][dictionary] of `{argument name: argument value}` pairs.
256
247
257
-
Since a dictionary can be iterated, `kwargs` can be passed to any other function which takes an iterable.
248
+
Since a dictionary can be iterated over, `kwargs` can be passed to any other function which takes an iterable.
258
249
Although `**kwargs` is commonly juxtaposed with `*args`, it doesn't have to be.
259
250
260
-
Following is an example of an arbitrary number of key-value pairs being passed to a function:
251
+
An arbitrary number of key-value pairs being passed to a function:
261
252
262
253
```python
263
254
>>>defadd(**kwargs):
264
-
...returnsum(kwargs.values())
265
-
...
255
+
...returnsum(kwargs.values())
256
+
266
257
>>>print(add(one=1, two=2, three=3))
267
258
6
268
259
```
269
260
270
261
Note that the `dict.values()` method is called to iterate through the `kwargs` dictionary values.
271
-
272
-
When iterating a dictionary the default is to iterate the keys.
273
-
274
-
Following is an example of an arbitrary number of key-value pairs being passed to a function that then iterates over `kwargs.keys()`:
262
+
When iterating over a dictionary the default is to iterate through the _keys_, so `dict.values()` needs to be specified explicitly.
263
+
Following is an example of an arbitrary number of key-value pairs being passed to a function that then iterates over `kwargs.items()`:
275
264
276
265
```python
277
266
>>>defconcat(**kwargs):
278
-
# Join concatenates the key names from `kwargs.keys()`
279
-
...return"".join(kwargs)
280
-
...
281
-
>>>print(concat(one=1, two=2, three=3))
282
-
one two three
267
+
...# Join concatenates the tuples from `kwargs.items()`
268
+
...return"".join((str(item) for item in kwargs.items()))
0 commit comments