tags:

views:

130

answers:

3
class x:
    def __init__(self):
        self.y=None
        self.sillyFunc(self.y)
    def sillyFunc(self,argument):
        if argument is None:
            argument='my_name_as_argument'
        self.printy()
    def printy(self):
        print self.y

According to me the above code should print >my_name_as_argument,where am i going wrong?

+3  A: 

In Python everything is an object and variables contain references to objects. When you make a function call it makes copies of the references. Some people including Guido van Rossum call this "Call by object reference". Important note from Wikipedia:

a function cannot change the value a variable references in its calling function.

The code as you posted it prints nothing at all. I think you mean to add this extra line to your program:

x()

This then results in the output: None. This is not surprising because you are printing the value of self.y but the only value you ever assign to self.y is None.

In Python, strings are immutable. Reassigning the value of argument only overwrites the local copy of the reference. It does not modify the original string.

As you asked in a comment, if you use a mutable object and you reassign the reference, again this doesn't do what you want - the original object is not affected. If you want to mutate a mutable object you can call a method that mutates it. Simply reassigning a reference does not change the original object.

If you want self.y to point to a new object then you have to assign the object reference directly to self.y.

Mark Byers
@Mark lets say i am not using string ,rather i assign some object to argument as in argument=Some_class() even then its not working
Bunny Rabbit
@Mark: this mechanism is often called “copy by reference”, AFAIR even in some text books (but I can’t provide a reference now).
Konrad Rudolph
@Konrad: Interesting. I have updated my post to make the first paragraph clearer.
Mark Byers
Python's model is called *call by sharing* - http://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing.
THC4k
+5  A: 

The assigment

argument='my_name_as_argument'

only affects the local variable argument. It doesn't change what self.y points to.

Richard Fearn
A: 

it depends on if you are changing the referenced object itself (and if this object is mutable) or replacing the reference to another object. See the following example, which uses a mutable list...

>>> def test(arg):
...     arg.append(123)
...     
... 
>>> s = []
>>> print s
[]
>>> test(s)
>>> print s
[123]
ahojnnes