1 00:00:00,230 --> 00:00:02,550 - In this video we're going to take a deeper look 2 00:00:02,550 --> 00:00:05,230 at Passing Arguments to Functions. 3 00:00:05,230 --> 00:00:07,280 Now, in most programming languages you have 4 00:00:07,280 --> 00:00:09,360 what are known as Pass-by-value 5 00:00:09,360 --> 00:00:11,010 and Pass-by-reference. 6 00:00:11,010 --> 00:00:13,860 With Pass-by-value you pass a copy 7 00:00:13,860 --> 00:00:16,330 of a value into a function 8 00:00:16,330 --> 00:00:18,840 and because it's a copy the function can do 9 00:00:18,840 --> 00:00:22,250 whatever it wants to the copy without having any effect 10 00:00:22,250 --> 00:00:24,330 on the original value in Memory 11 00:00:24,330 --> 00:00:25,593 wherever that may be. 12 00:00:26,760 --> 00:00:29,540 Many languages also support Pass-by-reference 13 00:00:29,540 --> 00:00:31,847 where the called function is told, 14 00:00:31,847 --> 00:00:35,520 "This is where you can find the original data in Memory." 15 00:00:35,520 --> 00:00:37,420 And therefore the called function 16 00:00:37,420 --> 00:00:39,560 having access to the original data, 17 00:00:39,560 --> 00:00:42,670 is able to potentially modify and manipulate 18 00:00:42,670 --> 00:00:44,420 that data directly. 19 00:00:44,420 --> 00:00:47,260 Now, in Python everything is Pass-by-reference 20 00:00:47,260 --> 00:00:49,400 because everything is an object 21 00:00:49,400 --> 00:00:51,680 and we don't directly manipulate the objects 22 00:00:51,680 --> 00:00:54,720 we manipulate the references to the objects. 23 00:00:54,720 --> 00:00:57,100 So when I pass a reference to an object 24 00:00:57,100 --> 00:01:00,440 into a function, a copy of the reference is made 25 00:01:00,440 --> 00:01:02,730 but not a copy of the object itself. 26 00:01:02,730 --> 00:01:05,410 Which turns out to be really important 27 00:01:05,410 --> 00:01:09,720 for performance because as you start getting into big data, 28 00:01:09,720 --> 00:01:12,240 the objects that you're manipulating 29 00:01:12,240 --> 00:01:16,320 may contain enormous amounts of information. 30 00:01:16,320 --> 00:01:18,320 Which if we had to copy that data 31 00:01:18,320 --> 00:01:22,950 into a function would take significant compute power. 32 00:01:22,950 --> 00:01:26,120 So, in Python, just reiterating. 33 00:01:26,120 --> 00:01:29,390 When you have a variable that refers to a value 34 00:01:29,390 --> 00:01:32,870 the variable is some place in Memory 35 00:01:32,870 --> 00:01:36,100 that just contains Addresses of objects 36 00:01:36,100 --> 00:01:39,240 and the names by which we refer to those objects. 37 00:01:39,240 --> 00:01:42,450 And then elsewhere in Memory are the objects themselves. 38 00:01:42,450 --> 00:01:45,177 So this would represent a case where we had said 39 00:01:45,177 --> 00:01:49,300 "assign to the variable X the value 7." 40 00:01:49,300 --> 00:01:51,720 So now that we've introduced the concepts 41 00:01:51,720 --> 00:01:54,290 of Pass-by-value and Pass-by-reference, 42 00:01:54,290 --> 00:01:57,350 let's try to hammer this point home a little bit more 43 00:01:57,350 --> 00:01:59,680 with an IPython session. 44 00:01:59,680 --> 00:02:02,480 And let's start out with the variable X 45 00:02:02,480 --> 00:02:04,060 initialized to 7. 46 00:02:04,060 --> 00:02:07,090 Which creates the variable that we just showed you 47 00:02:07,090 --> 00:02:09,200 in that preceding diagram. 48 00:02:09,200 --> 00:02:13,930 Now, turns out that every object in Memory at a given time, 49 00:02:13,930 --> 00:02:18,030 has a unique ID associated with it. 50 00:02:18,030 --> 00:02:20,800 And you can access that information 51 00:02:20,800 --> 00:02:23,800 via a function named ID. 52 00:02:23,800 --> 00:02:26,537 So, for example, if I go ahead and say 53 00:02:26,537 --> 00:02:30,460 "Give me the ID of whatever X refers to." 54 00:02:30,460 --> 00:02:32,350 It's going to give me back a number 55 00:02:32,350 --> 00:02:35,480 and by the way that number would probably be different 56 00:02:35,480 --> 00:02:38,320 on your system and if you execute 57 00:02:38,320 --> 00:02:40,370 a separate IPython sessions, 58 00:02:40,370 --> 00:02:42,520 each IPython session would probably have 59 00:02:42,520 --> 00:02:44,520 different numbers as well. 60 00:02:44,520 --> 00:02:48,830 This number is known as the object's identity 61 00:02:48,830 --> 00:02:51,920 and in many Python implementations 62 00:02:51,920 --> 00:02:55,890 this is actually the Memory Address of the object 63 00:02:55,890 --> 00:02:57,450 but that is not required, 64 00:02:57,450 --> 00:02:59,690 so you certainly shouldn't rely on it 65 00:02:59,690 --> 00:03:02,770 being the Memory Address of an object. 66 00:03:02,770 --> 00:03:06,040 Now, to help me get through this a little bit easier 67 00:03:06,040 --> 00:03:08,780 rather than typing a function definition, 68 00:03:08,780 --> 00:03:10,650 I'm going to paste one in 69 00:03:10,650 --> 00:03:12,310 for a function called "cube" 70 00:03:12,310 --> 00:03:14,170 which is going to calculate the cube 71 00:03:14,170 --> 00:03:16,400 of whatever number you give it. 72 00:03:16,400 --> 00:03:19,010 And, what I wanna do is demonstrate 73 00:03:19,010 --> 00:03:24,010 what the ID is of the variable that we receive 74 00:03:24,130 --> 00:03:26,840 of the object that we receive 75 00:03:26,840 --> 00:03:30,000 into the parameter called number. 76 00:03:30,000 --> 00:03:32,670 So, the first thing we do is define this function, 77 00:03:32,670 --> 00:03:34,320 it's going to print out that ID 78 00:03:34,320 --> 00:03:37,350 then it's going to return the cube of number. 79 00:03:37,350 --> 00:03:40,030 So let's define that, and let's go ahead 80 00:03:40,030 --> 00:03:43,440 and call cube with the number 7. 81 00:03:43,440 --> 00:03:47,580 And we can see that the ID is identical 82 00:03:47,580 --> 00:03:49,560 to back in snippet to. 83 00:03:49,560 --> 00:03:51,650 So the object that we're manipulating 84 00:03:51,650 --> 00:03:54,610 inside the cube function is in fact 85 00:03:54,610 --> 00:03:57,800 the object that X refers to, 86 00:03:57,800 --> 00:04:00,770 that initially contains the value 7. 87 00:04:00,770 --> 00:04:04,950 Now we didn't modify X, so X still contains the value 7 88 00:04:04,950 --> 00:04:08,000 after the call to cube in this case. 89 00:04:08,000 --> 00:04:11,500 However, it is possible that we can write functions 90 00:04:11,500 --> 00:04:14,740 that modify objects as well. 91 00:04:14,740 --> 00:04:18,280 Now, it turns out there's also another operator 92 00:04:18,280 --> 00:04:21,640 that can help you understand this as well, 93 00:04:21,640 --> 00:04:25,010 it's an operator called "is", 94 00:04:25,010 --> 00:04:28,220 which you can use to test whether two objects 95 00:04:28,220 --> 00:04:30,670 have the same identity. 96 00:04:30,670 --> 00:04:33,380 So, let's go ahead and paste in another version 97 00:04:33,380 --> 00:04:35,040 of the cube function here. 98 00:04:35,040 --> 00:04:37,570 In this case, we're introducing the "is" operator 99 00:04:37,570 --> 00:04:42,160 and what we're going to do is print out "number X is". 100 00:04:42,160 --> 00:04:42,993 No, I'm sorry, 101 00:04:42,993 --> 00:04:45,930 "number is x" and we're going to see a bulling value 102 00:04:45,930 --> 00:04:47,570 true or false. 103 00:04:47,570 --> 00:04:51,580 So, if number and x are the same object, 104 00:04:51,580 --> 00:04:53,780 that is they have the same identity. 105 00:04:53,780 --> 00:04:57,810 Then we'll get true, if they're different objects in Memory 106 00:04:57,810 --> 00:05:00,850 we'll get false, as a result of that. 107 00:05:00,850 --> 00:05:03,930 So if I define that and now once again 108 00:05:03,930 --> 00:05:06,110 let's go call "cube" 109 00:05:06,110 --> 00:05:08,923 and we'll give it "x" as an argument. 110 00:05:10,040 --> 00:05:13,120 And we can see that "number" is indeed "x" 111 00:05:13,120 --> 00:05:16,550 they are the same object in Memory. 112 00:05:16,550 --> 00:05:19,720 Now it is possible to pass 113 00:05:19,720 --> 00:05:24,640 both mutable and immutable objects as arguments 114 00:05:24,640 --> 00:05:26,730 to functions in Python. 115 00:05:26,730 --> 00:05:30,290 If you pass a mutable or modifiable object 116 00:05:30,290 --> 00:05:34,930 you'll be able to change the original value in the color. 117 00:05:34,930 --> 00:05:38,750 However, if you pass an immutable object 118 00:05:38,750 --> 00:05:41,400 and there are quite a number of those in Python, 119 00:05:41,400 --> 00:05:44,540 then any changes that appear to be made 120 00:05:44,540 --> 00:05:47,060 to the original object are actually 121 00:05:47,060 --> 00:05:49,770 creating new objects in Memory. 122 00:05:49,770 --> 00:05:53,630 So to help with this point, let me grab another copy 123 00:05:53,630 --> 00:05:56,663 of my "cube" function here and paste it in. 124 00:05:58,090 --> 00:06:00,450 And so, here we've defined another version 125 00:06:00,450 --> 00:06:01,840 of the "cube" function. 126 00:06:01,840 --> 00:06:03,640 And in the block of that function 127 00:06:03,640 --> 00:06:06,290 we're going to go ahead and display 128 00:06:06,290 --> 00:06:09,760 the ID of whatever object we're receiving 129 00:06:09,760 --> 00:06:12,660 by reference into the variable number. 130 00:06:12,660 --> 00:06:16,400 Then we're going to try to modify that object, 131 00:06:16,400 --> 00:06:18,970 now "number" is a local variable, 132 00:06:18,970 --> 00:06:21,370 it's the parameter of the "cube" function. 133 00:06:21,370 --> 00:06:24,300 And it's a copy of the reference 134 00:06:24,300 --> 00:06:26,470 that was stored in the variable "x" 135 00:06:26,470 --> 00:06:29,920 and passed into the "cube" function 136 00:06:29,920 --> 00:06:32,370 as we're gonna make that call in just a moment 137 00:06:32,370 --> 00:06:34,210 in the next snippet here. 138 00:06:34,210 --> 00:06:36,540 But because it's a copy of the reference, 139 00:06:36,540 --> 00:06:38,140 it's referring 140 00:06:38,140 --> 00:06:40,560 it's still referring to the original 141 00:06:40,560 --> 00:06:42,340 integer object in Memory 142 00:06:42,340 --> 00:06:45,350 but integer objects are immutable. 143 00:06:45,350 --> 00:06:48,840 So, anything that looks like it modifies an integer 144 00:06:48,840 --> 00:06:52,330 actually creates a new integer object in Memory. 145 00:06:52,330 --> 00:06:54,587 So with cube number stored 146 00:06:54,587 --> 00:06:58,070 the new reference in number and then to prove to you 147 00:06:58,070 --> 00:06:59,490 that is a different object, 148 00:06:59,490 --> 00:07:02,240 we once again display numbers ID 149 00:07:02,240 --> 00:07:04,990 then we return number to the caller. 150 00:07:04,990 --> 00:07:09,410 So, let's now call "cube" to see what happens here 151 00:07:09,410 --> 00:07:12,350 and we'll once again give it the variable "x". 152 00:07:12,350 --> 00:07:16,487 And as you can see, as we come into the function 153 00:07:16,487 --> 00:07:20,400 "x" has the ID shown here, which is the same 154 00:07:20,400 --> 00:07:22,360 ID that was displayed up above 155 00:07:22,360 --> 00:07:25,470 if we scroll back up, there's that same ID again. 156 00:07:25,470 --> 00:07:29,350 And after we do the "cube" we have a new ID 157 00:07:29,350 --> 00:07:33,080 of physically separate object in Memory. 158 00:07:33,080 --> 00:07:35,560 And of course, you can go and check 159 00:07:35,560 --> 00:07:38,850 the ID of "x" to see that it's still 160 00:07:38,850 --> 00:07:41,700 referring to the same object that it started with, 161 00:07:41,700 --> 00:07:46,070 and indeed it is the same ID once again. 162 00:07:46,070 --> 00:07:49,500 So, when you are working 163 00:07:49,500 --> 00:07:52,280 with objects in Python, 164 00:07:52,280 --> 00:07:55,210 they are Pass-by-reference into the functions 165 00:07:55,210 --> 00:07:58,100 and we were able to prove that by displaying 166 00:07:58,100 --> 00:08:02,113 the IDs of the objects before and inside of the cause. 167 00:08:03,020 --> 00:08:06,470 But, certain types of objects are immutable 168 00:08:06,470 --> 00:08:09,510 and therefore the function is unable 169 00:08:09,510 --> 00:08:12,160 to modify the original object in Memory. 170 00:08:12,160 --> 00:08:17,130 So some of the immutable items in Python include 171 00:08:17,130 --> 00:08:20,430 the numeric types integers and floating point numbers, 172 00:08:20,430 --> 00:08:24,300 strings, tuples are immutable as well. 173 00:08:24,300 --> 00:08:26,150 And there are a few other items 174 00:08:26,150 --> 00:08:28,623 that we'll see in later lessons.