Why doesn't python allow passing variables by reference [duplicate] - python

This question already has answers here:
How do I pass a variable by reference?
(39 answers)
Closed 6 months ago.
This probably fits more a discussion group, but I'm not proficient in the
innards of the language (or even the language itself). In any case, what's bugging me is:
If python is allowing interference (side effects) with outer scope using the nonlocal keyword, then why does it not allow a similar interference with function arguments by
permitting passing arguments by reference:
Possible right now:
>>> def outer():
x = 1
def inner():
nonlocal x
x = 2
print("inner:", x)
inner()
print("outer:", x)
>>> outer()
inner: 2
outer: 2
Why not - or what could go wrong if we had:
>>> def outer():
x = 1
def inner(byref x):
x = 2
print("inner:", x)
inner(x)
print("outer:", x)
>>> outer()
inner: 2
outer: 2
(using some keyword like 'byref' or 'nonlocal, just for illustration).

Python always passes parameters using reference value. Refer to this link here and especially rad the detailed response provided by the user pepr
Also this link has pretty detailed discussion on how exactly parameters are passed within python and also pass-by-reference can be simulated - refer to the EDIT of the accepted answer to this question.
In case, you want to delve deeper - please refer to this Effbot article that also contains some debate/discussions around the same topic.

This is not possible because Python does not have a concept of "variable" at all. All the names in a Python program are references to objects. So you can only pass a reference to an object when calling a function or method. This is called passing by reference value.
However, it is not possible to obtain a reference to an existing reference. In this respect, references are the only "non first class" citizens in the Python world.
There are two kinds of objects referenced by names in a program: immutable (e.g. string, int, tuple) an mutable (e.g. list, set, most user classes).
You can call methods on mutable objects that in fact modify the objects state, and this looks similar to passing a reference to the object in a language such as C++. Beyond that, the passing by reference does not make much sense in Python.
See Prahalad Deshpande's answer for some links.

Suppose you do allow reference arguments. What happens, then, when you do the following?
def f(byref x):
print x
print x
x = 3
class Foo(object):
def __init__(self):
self.count = 0
#property
def x(self):
count += 1
return count
f(Foo().x)
When is the getter called? How many times is it called? Does this print 1 twice, or does it print 1, then 2, or 2, then 3? Since there's no setter, what happens when you try to assign to x?
In another language, where variables are places to put things instead of names for values, this wouldn't be a problem. Foo().x would have a memory location once evaluated, and f would use that memory location for its x argument. In Python, it doesn't work like that. You can't pass in the memory location of 1 and change its contents, because then other code will find that 1 is magically 2 all of a sudden. Python's name semantics and attribute/item getter/setters make reference arguments even more confusing than in languages like C++, where they're already confusing and bug-prone.

In Python int objects are immutable. When you think you are changing the value of x, you are really creating a new int at a different memory location and getting x to reference that.

Related

Can I import and use a variable from a different python file in a function within a class [duplicate]

Suppose I have a function like:
def foo():
x = 'hello world'
How do I get the function to return x, in such a way that I can use it as the input for another function or use the variable within the body of a program? I tried using return and then using the x variable in another function, but I get a NameError that way.
For the specific case of communicating information between methods in the same class, it is often best to store the information in self. See Passing variables between methods in Python? for details.
def foo():
x = 'hello world'
return x # return 'hello world' would do, too
foo()
print(x) # NameError - x is not defined outside the function
y = foo()
print(y) # this works
x = foo()
print(x) # this also works, and it's a completely different x than that inside
# foo()
z = bar(x) # of course, now you can use x as you want
z = bar(foo()) # but you don't have to
Effectively, there are two ways: directly and indirectly.
The direct way is to return a value from the function, as you tried, and let the calling code use that value. This is normally what you want. The natural, simple, direct, explicit way to get information back from a function is to return it. Broadly speaking, the purpose of a function is to compute a value, and return signifies "this is the value we computed; we are done here".
Directly using return
The main trick here is that return returns a value, not a variable. So return x does not enable the calling code to use x after calling the function, and does not modify any existing value that x had in the context of the call. (That's presumably why you got a NameError.)
After we use return in the function:
def example():
x = 'hello world'
return x
we need to write the calling code to use the return value:
result = example()
print(result)
The other key point here is that a call to a function is an expression, so we can use it the same way that we use, say, the result of an addition. Just as we may say result = 'hello ' + 'world', we may say result = foo(). After that, result is our own, local name for that string, and we can do whatever we want with it.
We can use the same name, x, if we want. Or we can use a different name. The calling code doesn't have to know anything about how the function is written, or what names it uses for things.1
We can use the value directly to call another function: for example, print(foo()).2 We can return the value directly: simply return 'hello world', without assigning to x. (Again: we are returning a value, not a variable.)
The function can only return once each time it is called. return terminates the function - again, we just determined the result of the calculation, so there is no reason to calculate any further. If we want to return multiple pieces of information, therefore, we will need to come up with a single object (in Python, "value" and "object" are effectively synonyms; this doesn't work out so well for some other languages.)
We can make a tuple right on the return line; or we can use a dictionary, a namedtuple (Python 2.6+), a types.simpleNamespace (Python 3.3+), a dataclass (Python 3.7+), or some other class (perhaps even one we write ourselves) to associate names with the values that are being returned; or we can accumulate values from a loop in a list; etc. etc. The possibilities are endless..
On the other hand, the function returns whether you like it or not (unless an exception is raised). If it reaches the end, it will implicitly return the special value None. You may or may not want to do it explicitly instead.
Indirect methods
Other than returning the result back to the caller directly, we can communicate it by modifying some existing object that the caller knows about. There are many ways to do that, but they're all variations on that same theme.
If you want the code to communicate information back this way, please just let it return None - don't also use the return value for something meaningful. That's how the built-in functionality works.
In order to modify that object, the called function also has to know about it, of course. That means, having a name for the object that can be looked up in a current scope. So, let's go through those in order:
Local scope: Modifying a passed-in argument
If one of our parameters is mutable, we can just mutate it, and rely on the caller to examine the change. This is usually not a great idea, because it can be hard to reason about the code. It looks like:
def called(mutable):
mutable.append('world')
def caller():
my_value = ['hello'] # a list with just that string
called(my_value)
# now it contains both strings
If the value is an instance of our own class, we could also assign to an attribute:
class Test:
def __init__(self, value):
self.value = value
def called(mutable):
mutable.value = 'world'
def caller():
test = Test('hello')
called(test)
# now test.value has changed
Assigning to an attribute does not work for built-in types, including object; and it might not work for some classes that explicitly prevent you from doing it.
Local scope: Modifying self, in a method
We already have an example of this above: setting self.value in the Test.__init__ code. This is a special case of modifying a passed-in argument; but it's part of how classes work in Python, and something we're expected to do. Normally, when we do this, the calling won't actually check for changes to self - it will just use the modified object in the next step of the logic. That's what makes it appropriate to write code this way: we're still presenting an interface, so the caller doesn't have to worry about the details.
class Example:
def __init__(self):
self._words = ['hello']
def add_word(self):
self._words.append('world')
def display(self):
print(*self.words)
x = Example()
x.add_word()
x.display()
In the example, calling add_word gave information back to the top-level code - but instead of looking for it, we just go ahead and call display.3
See also: Passing variables between methods in Python?
Enclosing scope
This is a rare special case when using nested functions. There isn't a lot to say here - it works the same way as with the global scope, just using the nonlocal keyword rather than global.4
Global scope: Modifying a global
Generally speaking, it is a bad idea to change anything in the global scope after setting it up in the first place. It makes code harder to reason about, because anything that uses that global (aside from whatever was responsible for the change) now has a "hidden" source of input.
If you still want to do it, the syntax is straightforward:
words = ['hello']
def add_global_word():
words.append('world')
add_global_word() # `words` is changed
Global scope: Assigning to a new or existing global
This is actually a special case of modifying a global. I don't mean that assignment is a kind of modification (it isn't). I mean that when you assign a global name, Python automatically updates a dict that represents the global namespace. You can get that dict with globals(), and you can modify that dict and it will actually impact what global variables exist. (I.e., the return from globals() is the dictionary itself, not a copy.)5
But please don't. That's even worse of an idea than the previous one. If you really need to get the result from your function by assigning to a global variable, use the global keyword to tell Python that the name should be looked up in the global scope:
words = ['hello']
def replace_global_words():
global words
words = ['hello', 'world']
replace_global_words() # `words` is a new list with both words
Global scope: Assigning to or modifying an attribute of the function itself
This is a rare special case, but now that you've seen the other examples, the theory should be clear. In Python, functions are mutable (i.e. you can set attributes on them); and if we define a function at top level, it's in the global namespace. So this is really just modifying a global:
def set_own_words():
set_own_words.words = ['hello', 'world']
set_own_words()
print(*set_own_words.words)
We shouldn't really use this to send information to the caller. It has all the usual problems with globals, and it's even harder to understand. But it can be useful to set a function's attributes from within the function, in order for the function to remember something in between calls. (It's similar to how methods remember things in between calls by modifying self.) The functools standard library does this, for example in the cache implementation.
Builtin scope
This doesn't work. The builtin namespace doesn't contain any mutable objects, and you can't assign new builtin names (they'll go into the global namespace instead).
Some approaches that don't work in Python
Just calculating something before the function ends
In some other programming languages, there is some kind of hidden variable that automatically picks up the result of the last calculation, every time something is calculated; and if you reach the end of a function without returning anything, it gets returned. That doesn't work in Python. If you reach the end without returning anything, your function returns None.
Assigning to the function's name
In some other programming languages, you are allowed (or expected) to assign to a variable with the same name as the function; and at the end of the function, that value is returned. That still doesn't work in Python. If you reach the end without returning anything, your function still returns None.
def broken():
broken = 1
broken()
print(broken + 1) # causes a `TypeError`
It might seem like you can at least use the value that way, if you use the global keyword:
def subtly_broken():
global subtly_broken
subtly_broken = 1
subtly_broken()
print(subtly_broken + 1) # 2
But this, of course, is just a special case of assigning to a global. And there's a big problem with it - the same name can't refer to two things at once. By doing this, the function replaced its own name. So it will fail next time:
def subtly_broken():
global subtly_broken
subtly_broken = 1
subtly_broken()
subtly_broken() # causes a `TypeError`
Assigning to a parameter
Sometimes people expect to be able to assign to one of the function's parameters, and have it affect a variable that was used for the corresponding argument. However, this does not work:
def broken(words):
words = ['hello', 'world']
data = ['hello']
broken(data) # `data` does not change
Just like how Python returns values, not variables, it also passes values, not variables. words is a local name; by definition the calling code doesn't know anything about that namespace.
One of the working methods that we saw is to modify the passed-in list. That works because if the list itself changes, then it changes - it doesn't matter what name is used for it, or what part of the code uses that name. However, assigning a new list to words does not cause the existing list to change. It just makes words start being a name for a different list.
For more information, see How do I pass a variable by reference?.
1 At least, not for getting the value back. If you want to use keyword arguments, you need to know what the keyword names are. But generally, the point of functions is that they're an abstraction; you only need to know about their interface, and you don't need to think about what they're doing internally.
2 In 2.x, print is a statement rather than a function, so this doesn't make an example of calling another function directly. However, print foo() still works with 2.x's print statement, and so does print(foo()) (in this case, the extra parentheses are just ordinary grouping parentheses). Aside from that, 2.7 (the last 2.x version) has been unsupported since the beginning of 2020 - which was nearly a 5 year extension of the normal schedule. But then, this question was originally asked in 2010.
3Again: if the purpose of a method is to update the object, don't also return a value. Some people like to return self so that you can "chain" method calls; but in Python this is considered poor style. If you want that kind of "fluent" interface, then instead of writing methods that update self, write methods that create a new, modified instance of the class.
4 Except, of course, that if we're modifying a value rather than assigning, we don't need either keyword.
5 There's also a locals() that gives you a dict of local variables. However, this cannot be used to make new local variables - the behaviour is undefined in 2.x, and in 3.x the dict is created on the fly and assigning to it has no effect. Some of Python's optimizations depend on the local variables for a function being known ahead of time.
>>> def foo():
return 'hello world'
>>> x = foo()
>>> x
'hello world'
You can use global statement and then achieve what you want without returning value from
the function. For example you can do something like below:
def foo():
global x
x = "hello world"
foo()
print x
The above code will print "hello world".
But please be warned that usage of "global" is not a good idea at all and it is better to avoid usage that is shown in my example.
Also check this related discussion on about usage of global statement in Python.

Why does constructing a new object potentially alter the field of *every* instance of that class? [duplicate]

This question already has answers here:
"Least Astonishment" and the Mutable Default Argument
(33 answers)
Closed 6 years ago.
Here's a simplified version of the code in question:
class thing:
def __init__(self, data1, data2={'foo': 1}):
self.data2 = data2
self.data2['bar'] = data1
datas = ['FIRST', 'SECOND']
things = [thing(x) for x in datas]
for p in things:
print p.data2['bar']
I would expect this code to return:
FIRST
SECOND
However, it actually returns:
SECOND
SECOND
Why?
My best guess is:
that I am creating a single dictionary ur_dict = {'foo': 1},
that when I initialize an object of class thing I am not creating a new dictionary self.data2={'foo': 1} but rather initializing a reference to ur_dict,
and that when, in the constructor, I add the key-value pair bar: data1 to self.data2, I'm actually adding that key and value to ur_dict itself. This would update the data2 field of every single object in the list.
I tested this hypothesis by appending the following snippet to the code above:
things[0].data2['bar'] = 'FIRST'
for p in things:
print p.data2['bar']
Sure enough, the result is:
FIRST
FIRST
So I think my hypothesis is probably correct, but it's still mysterious to me. My question seems very related to this question --- when I create a default value in a constructor, is this value a class variable instead of an instance variable? Why doesn't python create new objects for default values of arguments in an object? Is there a good way to conceptualize or to catch this kind of error in the future? What are some good references to learn about what's going on here?
(Apologies in advance if I mangled jargon; I'm a mathematician by formal education.)
Edit: #CrazyPython[::-1] mentioned this is a property of functions, not classes or objects. I created an example of a function with a mutable default argument and I'm trying to figure out how to break it in the manner I experienced with objects and classes above. Came up with this:
EXPONENT = 1
def fooBar(x, y=EXPONENT):
return x**y
print EXPONENT
print foo(5)
EXPONENT = 2
print EXPONENT
print foo(5)
However, it returns:
1
5
2
5
What's a good way to "break" this to illustrate why not to use a mutable default argument here?
self.data2={'foo': 1} is a mutable default argument. Never do that. 99% of the time it's a mistake.
def foo(a, b={}):
...
is not equivalent to
def foo(a, b=None):
if b is None:
b = {}
b is not reconstructed every time. It's the same object.
Is there a good way to conceptualize or to catch this kind of error in the future?
Use PyCharm or another good editor
when I create a default value in a constructor, is this value a class variable instead of an instance variable?
no no no no no no. It's tied to the function, not the class or instance. This is behavior applies to all functions. It has nothing to do with classes or your linked question.
Why doesn't python create new objects for default values of arguments in an object?
Performance and compatibility. Constructing an object is a potentially expensive operation.
Addendum
Please use CamelCase for classes. Not doing so is a PEP 8 violation, which is the Python official style guide.
Get a decent editor. Personally, I recommend PyCharm. (I'm no salesperson) It's free.
PyCharm can rename variables, highlight PEP 8 errors, perform advanced auto complete, type checking, spot mutable default arguments, and much more.
You aren't inheriting off of object. That's bad.*
Why does this python code alter the field of every object in a list?
Without context, that's a bad title. It asks about the code. When we read the title, we don't have the code.
Making it more clear
When a function is stated, the default arguments are evaluated. (not when it is executed, when it is stated) They are tied to the function. When a function is executed, a copy of the default arguments is not produced. You directly modify the default arguments. The next function that is called will receive the same object, with modifications.
*You seem to be a professor or the like. Please don't be offended by a meme. That's just the risk of getting advice from the internet.

Function arguments (in Python for example)

What are [function] arguments? What are they used for?
I started learning Python very recently; I'm new to programming and I apologize for this basic question.
In every Python tutorial I go through they talk about arguments. I have looked for the answer to this question and have found many answers but they are just a little too hard for me to understatnd. I may just be missing some conceptual background.
So... when I define a function, what are the things in parenthesis used for?
Example:
def hi( This is the part that i dont get):
print 'hi'
Edit:
Two follow-up questions related to this one were later closed and merged here, hence the partial out-of-context trait of some of the answers.
The follow-up questions were: [paraphrased]
Can arguments only be used for input ?
what are other examples of the use of arguments ?
Why use arguments, rather than having the function call raw_input ?
Why is the concept of argument passing described as such a powerful thing? it seems to me we're merely using them to replace stuff the user could have type on the keyboard.
In a few words, they're data that gets "passed into" the function to tell it what to do. Wikipedia has details.
http://en.wikipedia.org/wiki/Function_argument
For instance, your hi() function might need to know who to say hello to:
def hi(person):
print "Hi there " + person + ", how are you?"
Or a mathematical function might need a value to operate on:
def square(x):
return x * x
This is not a Python question, but rather a generic programming question. A very basic one.
Before answering the question about arguments, and in view of the other questions you asked, it is useful to discuss the concept of variables.
A variable is a named piece of memory where information of interest to the underlying program can be stored and retrieved. In other words, it is a symbolic name, chosen by the programmer, that is associated to its contents. Using various language constructs generally known as assignments, the programmer can read or write the contents of a variable.
It is important to note that the value (i.e. the content) of a variable needn't be defined when the program is written. It is only necessary at run-time. This allows the program to describe actions to be performed on symbolic elements without knowing exactly the value these elements have. Consider this snippet, part of a bigger program:
# ... some logic above
ball_volume = 4.0 / 3 * math.pi * ball_radius
if ball_volume > 200:
print ("Man, that's a big ball")
# ... more logic below
At the time the program is written one doesn't need to know the actual value of ball_radius; yet, with the assumption that this variable will contain the numeric value of some hypothetical ball, the snippet is capable of describing how to compute the ball's volume. In this fashion, when the program is running, and somehow (more on this later) the ball_radius variable has been initialized with some appropriate value, the variable ball_volume can too be initialized and used, here in the conditional statement (if), and possibly below. (At some point the variable may go out-of-scope, but this concept which controls when particular variables are accessible to the program is well beyond this primer).
In some languages the type of data that may be associated with a particular variable needs to be explicitly defined and cannot change. For example some variables could hold only integer values, other variables string values (text) etc. In Python there is no such restriction, a variable can be assigned and re-assigned to any type of data, but of course, the programmer needs to keep track of this for example to avoid passing some text data to a mathematical function.
The data stored inside variable may come from very different sources. Many of the examples provided in tutorials and introductory documentation have this data coming from keyboard input (as when using raw_input as mentioned in some of your questions). That is because it allows interactive tests by the people trying out these tutorial snippets. But the usefulness of programs would be rather limited if variables only get their data from interactive user input. There are many other sources and this is what makes programming so powerful: variables can be initialized with data from:
databases
text files or files various text-base formats (XML, JSON, CSV..)
binary files with various formats
internet connections
physical devices: cameras, temperature sensors...
In a nutshell, Arguments, also called Parameters, are variables passed to the function which [typically] are used to provide different output and behavior from the function. For example:
>>> def say_hello(my_name):
... print("Hello,", my_name, "!")
>>> say_hello("Sam")
Hello, Sam !
>>> customer_name = "Mr Peter Clark" #imagine this info came from a database
>>> # ...
>>> say_hello(customer_name)
Hello, Mr Peter Clark !
>>>
In the example above, my_name is just like any local variable of the say_hello function; this allows the function to define what it will do with the underlying value when the function is called, at run-time.
At run-time, the function can be called with an immediate value (a value that is "hard-coded" in the logic, such as "Sam" in the example), or with [the value of] another variable (such as customer_name). In both cases the value of the function's my_name variable gets assigned some value, "Sam" and "Mr Peter Clark" respectively. In the latter case, this value is whatever the customer_name variable contains. Note that the names of the variables used inside the function (my_name) and when the function is called (customer_name) do not need to be the same. (these are called the "formal parameter(s)" and the "actual parameters" respectively)
Note that while typically most arguments as passed as input to a function, in some conditions, they can be used as output, i.e. to provide new/modified values at the level of the logic which called the function. Doing so requires using, implicitly or explicitly, the proper calling convention specification (See Argument passing conventions below)
Now... beyond this very basic understanding of the purpose of parameters, things get a little more complicated than that (but not much). I'll discuss these additional concepts in general and illustrate them as they apply to Python.
Default values for arguments (aka "optional" arguments)
When the function is declared it may specify the default value for some parameters. These values are used for the parameters which are not specified when the function is called. For obvious reasons these optional parameters are found at the end of the parameter list (otherwise the language compiler/interpreter may have difficulty figuring out which parameter is which...)
>>> def say_hello(dude = "Sir"):
... print("Hello,", dude, "!")
...
>>> say_hello()
Hello, Sir !
>>> say_hello("William Gates")
Hello, Bill ! #just kidding ;-)
Hello, William Gates ! # but indeed. works as the original function when param
# is specified
Variable number of parameters
In some cases it may be handy to define a function so that it may accept a variable number of parameters. While such lists of parameter values ultimately get passed in some kind of container (list, array, collection...) various languages offers convenient ways of accessing such parameter values.
>>> def add_many(operand1, *operands):
... Sum = operand1
... for op in operands:
... Sum += op
... return Sum
...
>>> add_many(1, 3, 5, 7, 20)
36
>>> add_many(1, 3)
4
Named Arguments (Keyword Arguments)
With Python and a few other languages, it is possible to explicitly name the arguments when calling the function. Whereby argument passing is by default based a positional basis ("1st argument, 2nd argument etc.), Python will let you name the arguments and pass them in any order. This is mostly a syntactic nicety, but can be useful, in combination with default arguments for functions that accept very many arguments. It is also a nice self-documenting feature.
>>> def do_greetings(greeting, person):
... print (greeting, "dear", person, "!")
...
>>> do_greetings(person="Jack", greeting="Good evening")
Good evening dear Jack !
In Python, you can even pass a dictionary in lieu of several named arguments for example, with do_greetingsas-is, imagine you have a dictionary like:
>>> my_param_dict = {"greeting":"Aloha", "person":"Alan"}
>>> do_greetings(**my_param_dict)
Aloha dear Alan !
In closing, and while the fancy ways of passing arguments, and the capability for methods to handle variable number of arguments are useful features of various languages, two key concepts need to be mentioned:
Argument passing convention : by value or by reference
So far all the functions we used didn't alter the value of the parameters passed to them. We can imagine however many instances when functions may want to do this, either to perform some conversion or computation on the said values, for its own internal use, or to effectively change the value of the variable so that the changes are reflected at the level of logic which called the function. That's where argument passing conventions come handy...
arguments which are passed by value may be altered by the function for its own internal computations but are not changed at the level of the calling method.
arguments which are passed by reference will reflect changes made to them, at the level of the calling method.
Each language specifies the ways that arguments are passed. A typical convention is to pass integers, numberic values and other basic types by value and to pass objects by reference. Most language also offer keyword that allow altering their default convention.
In python all arguments are passed by reference. However a few variables types are immutable (numbers, strings, tuples...) and they can therefore not be altered by the function.
Implicit "self" or "this" argument of class methods
In object oriented languages, methods (i.e. functions within a class) receive an extra argument that is the value of underlying object (the instance of the class), allowing the method to use various properties members of the class in its computation and/or to alter the value of some of these properties.
in Python, this argument is declared at the level of the method definition, but is passed implicitly. Being declared, it may be named most anything one wishes, although by convention this is typically called self.
>>> class Accumulator:
... def __init__(self, initialValue = 0):
... self.CurValue = initialValue
... def Add(self, x):
... self.CurValue += x
... return self.CurValue
...
>>> my_accu = Accumulator(10)
>>> my_accu.Add(5)
15
>>> my_accu.Add(3)
18
In that case for using arguments, it is simply a demo on how to use them, not the most effective perhaps as you demonstrated. Functions are very useful. for example if i wanted to add two numbers:
def add(num1, num2):
x = num1 + num2
return x
add(1,3)
Functions are useful for performing repetitive tasks, let's say in your example you had to say hello to hundreds of names, instead of having to do a loop of that raw_input() function to read their name and add some text to it you could simply call a function to perform the task and pass arguments (the persons name to it).
Per your second question, arguments are just variables passed to the function, so whatever variable you pass to it from the outside, for example I pass numbers 1 and 3 to my function add on the inside of that function they are simply referred to as num1 num2.
In your case with passing too many arguments would yield this:
>>> add(1,2)
3
>>> add(1,2,3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: add() takes exactly 2 arguments (3 given)
>>>
Best of luck! and feel free to shoot me an email if you need further help (sbrichards (at) mit.edu)
The stuff in the parentheses are called arguments. Basically these are variables that you want the function to work with. For example, say you have a function, and you want it to print a word when you call it. With arguments, you can define what that word will be. Here is an example:
def hi(word):
print word
now, if I do something like this:
hi('Hello!')
it will print:
'Hello!'
hi() gets passed 'Hello!' as a variable called word, and then it prints that word.
In your example they are not used.
If your function needs to behave differently depending on what arguments you give it, then what's arguments are for.
def hi_name(name):
print 'Hi ' + name
hi_name("John doe")
This prints "Hi John Doe".
Now back to the basics about functions.
An argument is a special variable that exists only in that function.
In your example you have a function that takes 2 arguments:
def add(num1,num2):
x = num1 + num2
return x
When I call this function with add(), I have to add in the parentheses what I want num1 and num2 to be. In your case, you have 1 and 3, so you call it like this add(1,3).
What you're saying there is that you want to call add() and you want the first argument, num1 to be equal to 1, and the second argument, num2, to be equal to 3.
def main(a, b):
print(a)
print(b)
main(3, 5)
This is a basic example of a function with parameters, check for more information here.
output:
3
5
Functions would be useless if you can't give them information they should handle.
Arguments are such information.
def GiveMeANumberAndIDuplicateIt(x):
return x * 2
def DontGiveMeAnythingAtAll():
return None

Python arguments- how do you use them? [duplicate]

What are [function] arguments? What are they used for?
I started learning Python very recently; I'm new to programming and I apologize for this basic question.
In every Python tutorial I go through they talk about arguments. I have looked for the answer to this question and have found many answers but they are just a little too hard for me to understatnd. I may just be missing some conceptual background.
So... when I define a function, what are the things in parenthesis used for?
Example:
def hi( This is the part that i dont get):
print 'hi'
Edit:
Two follow-up questions related to this one were later closed and merged here, hence the partial out-of-context trait of some of the answers.
The follow-up questions were: [paraphrased]
Can arguments only be used for input ?
what are other examples of the use of arguments ?
Why use arguments, rather than having the function call raw_input ?
Why is the concept of argument passing described as such a powerful thing? it seems to me we're merely using them to replace stuff the user could have type on the keyboard.
In a few words, they're data that gets "passed into" the function to tell it what to do. Wikipedia has details.
http://en.wikipedia.org/wiki/Function_argument
For instance, your hi() function might need to know who to say hello to:
def hi(person):
print "Hi there " + person + ", how are you?"
Or a mathematical function might need a value to operate on:
def square(x):
return x * x
This is not a Python question, but rather a generic programming question. A very basic one.
Before answering the question about arguments, and in view of the other questions you asked, it is useful to discuss the concept of variables.
A variable is a named piece of memory where information of interest to the underlying program can be stored and retrieved. In other words, it is a symbolic name, chosen by the programmer, that is associated to its contents. Using various language constructs generally known as assignments, the programmer can read or write the contents of a variable.
It is important to note that the value (i.e. the content) of a variable needn't be defined when the program is written. It is only necessary at run-time. This allows the program to describe actions to be performed on symbolic elements without knowing exactly the value these elements have. Consider this snippet, part of a bigger program:
# ... some logic above
ball_volume = 4.0 / 3 * math.pi * ball_radius
if ball_volume > 200:
print ("Man, that's a big ball")
# ... more logic below
At the time the program is written one doesn't need to know the actual value of ball_radius; yet, with the assumption that this variable will contain the numeric value of some hypothetical ball, the snippet is capable of describing how to compute the ball's volume. In this fashion, when the program is running, and somehow (more on this later) the ball_radius variable has been initialized with some appropriate value, the variable ball_volume can too be initialized and used, here in the conditional statement (if), and possibly below. (At some point the variable may go out-of-scope, but this concept which controls when particular variables are accessible to the program is well beyond this primer).
In some languages the type of data that may be associated with a particular variable needs to be explicitly defined and cannot change. For example some variables could hold only integer values, other variables string values (text) etc. In Python there is no such restriction, a variable can be assigned and re-assigned to any type of data, but of course, the programmer needs to keep track of this for example to avoid passing some text data to a mathematical function.
The data stored inside variable may come from very different sources. Many of the examples provided in tutorials and introductory documentation have this data coming from keyboard input (as when using raw_input as mentioned in some of your questions). That is because it allows interactive tests by the people trying out these tutorial snippets. But the usefulness of programs would be rather limited if variables only get their data from interactive user input. There are many other sources and this is what makes programming so powerful: variables can be initialized with data from:
databases
text files or files various text-base formats (XML, JSON, CSV..)
binary files with various formats
internet connections
physical devices: cameras, temperature sensors...
In a nutshell, Arguments, also called Parameters, are variables passed to the function which [typically] are used to provide different output and behavior from the function. For example:
>>> def say_hello(my_name):
... print("Hello,", my_name, "!")
>>> say_hello("Sam")
Hello, Sam !
>>> customer_name = "Mr Peter Clark" #imagine this info came from a database
>>> # ...
>>> say_hello(customer_name)
Hello, Mr Peter Clark !
>>>
In the example above, my_name is just like any local variable of the say_hello function; this allows the function to define what it will do with the underlying value when the function is called, at run-time.
At run-time, the function can be called with an immediate value (a value that is "hard-coded" in the logic, such as "Sam" in the example), or with [the value of] another variable (such as customer_name). In both cases the value of the function's my_name variable gets assigned some value, "Sam" and "Mr Peter Clark" respectively. In the latter case, this value is whatever the customer_name variable contains. Note that the names of the variables used inside the function (my_name) and when the function is called (customer_name) do not need to be the same. (these are called the "formal parameter(s)" and the "actual parameters" respectively)
Note that while typically most arguments as passed as input to a function, in some conditions, they can be used as output, i.e. to provide new/modified values at the level of the logic which called the function. Doing so requires using, implicitly or explicitly, the proper calling convention specification (See Argument passing conventions below)
Now... beyond this very basic understanding of the purpose of parameters, things get a little more complicated than that (but not much). I'll discuss these additional concepts in general and illustrate them as they apply to Python.
Default values for arguments (aka "optional" arguments)
When the function is declared it may specify the default value for some parameters. These values are used for the parameters which are not specified when the function is called. For obvious reasons these optional parameters are found at the end of the parameter list (otherwise the language compiler/interpreter may have difficulty figuring out which parameter is which...)
>>> def say_hello(dude = "Sir"):
... print("Hello,", dude, "!")
...
>>> say_hello()
Hello, Sir !
>>> say_hello("William Gates")
Hello, Bill ! #just kidding ;-)
Hello, William Gates ! # but indeed. works as the original function when param
# is specified
Variable number of parameters
In some cases it may be handy to define a function so that it may accept a variable number of parameters. While such lists of parameter values ultimately get passed in some kind of container (list, array, collection...) various languages offers convenient ways of accessing such parameter values.
>>> def add_many(operand1, *operands):
... Sum = operand1
... for op in operands:
... Sum += op
... return Sum
...
>>> add_many(1, 3, 5, 7, 20)
36
>>> add_many(1, 3)
4
Named Arguments (Keyword Arguments)
With Python and a few other languages, it is possible to explicitly name the arguments when calling the function. Whereby argument passing is by default based a positional basis ("1st argument, 2nd argument etc.), Python will let you name the arguments and pass them in any order. This is mostly a syntactic nicety, but can be useful, in combination with default arguments for functions that accept very many arguments. It is also a nice self-documenting feature.
>>> def do_greetings(greeting, person):
... print (greeting, "dear", person, "!")
...
>>> do_greetings(person="Jack", greeting="Good evening")
Good evening dear Jack !
In Python, you can even pass a dictionary in lieu of several named arguments for example, with do_greetingsas-is, imagine you have a dictionary like:
>>> my_param_dict = {"greeting":"Aloha", "person":"Alan"}
>>> do_greetings(**my_param_dict)
Aloha dear Alan !
In closing, and while the fancy ways of passing arguments, and the capability for methods to handle variable number of arguments are useful features of various languages, two key concepts need to be mentioned:
Argument passing convention : by value or by reference
So far all the functions we used didn't alter the value of the parameters passed to them. We can imagine however many instances when functions may want to do this, either to perform some conversion or computation on the said values, for its own internal use, or to effectively change the value of the variable so that the changes are reflected at the level of logic which called the function. That's where argument passing conventions come handy...
arguments which are passed by value may be altered by the function for its own internal computations but are not changed at the level of the calling method.
arguments which are passed by reference will reflect changes made to them, at the level of the calling method.
Each language specifies the ways that arguments are passed. A typical convention is to pass integers, numberic values and other basic types by value and to pass objects by reference. Most language also offer keyword that allow altering their default convention.
In python all arguments are passed by reference. However a few variables types are immutable (numbers, strings, tuples...) and they can therefore not be altered by the function.
Implicit "self" or "this" argument of class methods
In object oriented languages, methods (i.e. functions within a class) receive an extra argument that is the value of underlying object (the instance of the class), allowing the method to use various properties members of the class in its computation and/or to alter the value of some of these properties.
in Python, this argument is declared at the level of the method definition, but is passed implicitly. Being declared, it may be named most anything one wishes, although by convention this is typically called self.
>>> class Accumulator:
... def __init__(self, initialValue = 0):
... self.CurValue = initialValue
... def Add(self, x):
... self.CurValue += x
... return self.CurValue
...
>>> my_accu = Accumulator(10)
>>> my_accu.Add(5)
15
>>> my_accu.Add(3)
18
In that case for using arguments, it is simply a demo on how to use them, not the most effective perhaps as you demonstrated. Functions are very useful. for example if i wanted to add two numbers:
def add(num1, num2):
x = num1 + num2
return x
add(1,3)
Functions are useful for performing repetitive tasks, let's say in your example you had to say hello to hundreds of names, instead of having to do a loop of that raw_input() function to read their name and add some text to it you could simply call a function to perform the task and pass arguments (the persons name to it).
Per your second question, arguments are just variables passed to the function, so whatever variable you pass to it from the outside, for example I pass numbers 1 and 3 to my function add on the inside of that function they are simply referred to as num1 num2.
In your case with passing too many arguments would yield this:
>>> add(1,2)
3
>>> add(1,2,3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: add() takes exactly 2 arguments (3 given)
>>>
Best of luck! and feel free to shoot me an email if you need further help (sbrichards (at) mit.edu)
The stuff in the parentheses are called arguments. Basically these are variables that you want the function to work with. For example, say you have a function, and you want it to print a word when you call it. With arguments, you can define what that word will be. Here is an example:
def hi(word):
print word
now, if I do something like this:
hi('Hello!')
it will print:
'Hello!'
hi() gets passed 'Hello!' as a variable called word, and then it prints that word.
In your example they are not used.
If your function needs to behave differently depending on what arguments you give it, then what's arguments are for.
def hi_name(name):
print 'Hi ' + name
hi_name("John doe")
This prints "Hi John Doe".
Now back to the basics about functions.
An argument is a special variable that exists only in that function.
In your example you have a function that takes 2 arguments:
def add(num1,num2):
x = num1 + num2
return x
When I call this function with add(), I have to add in the parentheses what I want num1 and num2 to be. In your case, you have 1 and 3, so you call it like this add(1,3).
What you're saying there is that you want to call add() and you want the first argument, num1 to be equal to 1, and the second argument, num2, to be equal to 3.
def main(a, b):
print(a)
print(b)
main(3, 5)
This is a basic example of a function with parameters, check for more information here.
output:
3
5
Functions would be useless if you can't give them information they should handle.
Arguments are such information.
def GiveMeANumberAndIDuplicateIt(x):
return x * 2
def DontGiveMeAnythingAtAll():
return None

What is "lambda binding" in Python? [duplicate]

This question already has answers here:
What do lambda function closures capture?
(7 answers)
Closed 6 months ago.
I understand what are lambda functions in Python, but I can't find what is the meaning of "lambda binding" by searching the Python docs.
A link to read about it would be great.
A trivial explained example would be even better.
Thank you.
First, a general definition:
When a program or function statement
is executed, the current values of
formal parameters are saved (on the
stack) and within the scope of the
statement, they are bound to the
values of the actual arguments made in
the call. When the statement is
exited, the original values of those
formal arguments are restored. This
protocol is fully recursive. If within
the body of a statement, something is
done that causes the formal parameters
to be bound again, to new values, the
lambda-binding scheme guarantees that
this will all happen in an orderly
manner.
Now, there is an excellent python example in a discussion here:
"...there is only one binding for x: doing x = 7 just changes the value in the pre-existing binding. That's why
def foo(x):
a = lambda: x
x = 7
b = lambda: x
return a,b
returns two functions that both return 7; if there was a new binding after the x = 7, the functions would return different values [assuming you don't call foo(7), of course. Also assuming nested_scopes]...."
I've never heard that term, but one explanation could be the "default parameter" hack used to assign a value directly to a lambda's parameter. Using Swati's example:
def foo(x):
a = lambda x=x: x
x = 7
b = lambda: x
return a,b
aa, bb = foo(4)
aa() # Prints 4
bb() # Prints 7
Where have you seen the phrase used?
"Binding" in Python generally refers to the process by which a variable name ends up pointing to a specific object, whether by assignment or parameter passing or some other means, e.g.:
a = dict(foo="bar", zip="zap", zig="zag") # binds a to a newly-created dict object
b = a # binds b to that same dictionary
def crunch(param):
print param
crunch(a) # binds the parameter "param" in the function crunch to that same dict again
So I would guess that "lambda binding" refers to the process of binding a lambda function to a variable name, or maybe binding its named parameters to specific objects? There's a pretty good explanation of binding in the Language Reference, at http://docs.python.org/ref/naming.html

Categories