2

i need help-i try to send value to method like in c++ by ref/by ptr how can i do it?

to exmple:

 def test(x): x=3 x=2 test(x) print(x) 

In this case x a local variable in test method and will not change the "original" X so how can i change the "original" X? thanks

3
  • stackoverflow.com/questions/1145722/… Commented Oct 16, 2013 at 16:47
  • 2
    Don't try to write other languages in Python (or, indeed, Python in other languages). Commented Oct 16, 2013 at 16:51
  • 3
    @BurhanKhalid There is no distinction between mutable and immutable objects either (as far as argument passing is concerned). Everything is passed the same way -- for example, immutable objects are not copied -- the only difference is that it's slightly harder to observe this with immutable objects. Commented Oct 16, 2013 at 16:52

2 Answers 2

4

In some ways, all calls in Python are called with references. In fact, all variables are references in a sense. But some types, like int from your example, cannot be changed.

In the case of, say, a list, the functionality you're looking for is trivial:

def change_it(some_list): some_list.append("world") foo = ["hello"] change_it(foo) print(foo) # prints ['hello', 'world'] 

Note, however, that reassigning the parameter variable some_list does not change the value in the calling context.

If you're asking this question, though, you're probably looking to do something like set two or three variables using one function. In that case, you're looking for something like this:

def foo_bar(x, y, z): return 2*x, 3*y, 4*z x = 3 y = 4 z = 5 x, y, z = foo_bar(x, y, z) print(y) # prints 12 

Of course, you can do anything in Python, but that doesn't mean you should. In the fashion of the TV show Mythbusters, here's something that does what you're looking for

import inspect def foo(bar): frame = inspect.currentframe() outer = inspect.getouterframes(frame)[1][0] outer.f_locals[bar] = 2 * outer.f_locals[bar] a = 15 foo("a") print(a) # prints 30 

or even worse:

import inspect import re def foo(bar): # get the current call stack my_stack = inspect.stack() # get the outer frame object off of the stack outer = my_stack[1][0] # get the calling line of code; see the inspect module documentation # only works if the call is not split across multiple lines of code calling_line = my_stack[1][4][0] # get this function's name my_name = my_stack[0][3] # do a regular expression search for the function call in traditional form # and extract the name of the first parameter m = re.search(my_name + "\s*\(\s*(\w+)\s*\)", calling_line) if m: # finally, set the variable in the outer context outer.f_locals[m.group(1)] = 2 * outer.f_locals[m.group(1)] else: raise TypeError("Non-traditional function call. Why don't you just" " give up on pass-by-reference already?") # now this works like you would expect a = 15 foo(a) print(a) # but then this doesn't work: baz = foo_bar baz(a) # raises TypeError # and this *really*, disastrously doesn't work a, b = 15, 20 foo_bar, baz = str, foo_bar baz(b) and foo_bar(a) print(a, b) # prints 30, 20 

Please, please, please, don't do this. I only put it in here to inspire the reader to look into some of the more obscure parts of Python.

Sign up to request clarification or add additional context in comments.

4 Comments

Not call by reference, call be reference objects. All parameters are passed by reference by default.
Good point. Fixing it now
Your examples using f_locals doesn't work in the general case. whenever the given name is a fast local (as it is for variables in local scope of most functions), then the f_locals dict won't contain the value, it's in f_localsplus, which is not accessible from normal python. There's no reasonable way to push data from f_locals into f_localsplus (except with ctypes).
@dequestarmappartialsetattr good to know. I didn't intend it to be an actual usable method, but more a way to show off the inspect module. Thanks, though. I learned something
1

As far as I am aware, this doesn't exist in Python (although a similar thing occurs if you pass mutable objects to a function). You would do either

def test(): global x x = 3 test() 

or

def test(x): return 3 x = test(x) 

The second of these is much preferred.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.