Python for .NET Developers Transcripts
Chapter: The Python Language
Lecture: Concept: Python function overloading
Login or
purchase this course
to watch this video and the rest of the course contents.
0:00
Let's quickly review functions in Python. Here, we have a function called named arguments and it has one required positional parameter
0:10
called name, ironically. And then, it takes arbitrary positional arguments *args, remember that's like params, object array but we just say *.
0:20
And then, we can pass arbitrary keyword arguments to it and that appears in the dictionary, kwargs. I don't really love that style because
0:30
it doesn't tell me what arbitrary keywords I could pass. A way to accomplish almost exactly the same thing
0:38
like 90% of the time, if you just have default values like this times here. If you could've said times=1
0:45
but you don't have to, well, you could also just say times=1 as a default argument and it turns out the editors give you way more help
0:54
because if ask what is the signature of named args in the top one, it tells me I can pass anything. I don't know what type those are.
1:02
I don't know the values of them, the names of the parameters are, the list of options, nothing. And this is prevalent in Python
1:09
and I kind of hate it because usually what you can do is just name out the optional named arguments as default values
1:17
and folks can decide to pass them by name or not, right? So really, really nice to do this second one. I feel it's better than the top one.
1:26
There's a few use cases where you really don't know what could go in there 'cause your passing it along but most of the time, you actually know.
1:32
It's just you don't want to say. So anyway, I kind of like the bottom say hello version over the named args.
1:38
One thing you do want to be careful about though with these default values here, these can be dangerous.
1:44
So see this say no, as in no, no, no, don't do this? This one actually is a bit of an anti-pattern and let me tell you why.
1:52
If you pass a mutable type or if you set a mutable type for the default value, this could go really, really wrong and let me tell you how.
2:01
You might think when you call this function the default value is created and set each time the function is called
2:08
but that's not actually where the default value is set. The default value is set when that module, that file
2:14
is loaded, once, ever, so there is a singleton list that is the default value for names. That singleton is, well, it's a singleton
2:26
and that means it's shared by everyone who calls that function every time. So imagine something happens inside
2:33
that function where names is altered, right? An item is added or removed to names if it's empty. Well, guess what.
2:40
Now the default value has that change reflected in it or worse, if this function returns names makes some changes, adds more names
2:48
and returns that list, then it's open to the rest of the program to possibly add or remove items from that default value
2:55
so never, never put a mutable value here. The way you would accomplish this is you would say names=None and then, in that function you say
3:03
if names is None, names=[], like this. And that way, you get a new copy every time you call it not the one that got set when you imported the module.
3:13
That's super not obvious, so I wanted to call it out and make it really clear. This seems okay but it turns out to actually be an anti-pattern.