Carrying variables over from function to function

I

Ivan Shevanski

Alright heres my problem. . .Say I want to carry over a variable from one
function to another or even another run of the same function. Is that
possible? Heres a quick example of what I'm talking about.

def abc():
x = 1
y = x + 1
print y

def abcd():
y = x + 1
print y

abc()
abcd()

the output would be:
Traceback (most recent call last):
File "(stdin)", line 1, in ?
File "(stdin)", line 2, in abcd
NameError: global name 'x' is not defined



See, I want y in the second function to equal 4, carrying the x from the
first function over to the next. Is there any way to do this?



-Ivan

_________________________________________________________________
Don’t just search. Find. Check out the new MSN Search!
http://search.msn.click-url.com/go/onm00200636ave/direct/01/
 
R

Roy Smith

Ivan Shevanski said:
Alright heres my problem. . .Say I want to carry over a variable from one
function to another or even another run of the same function. Is that
possible?

You want one of two things.

The most obvious would be a global variable. Something like this:

def abc():
global x
x = 1
y = x + 1
print y

def abcd():
global x
y = x + 1
print y

This works, and is sometimes even the right thing to do, but in general,
good software design looks for ways to decouple functions from each other
and generally frowns on the use of global variables.

More likely, what you really want to do is declare a class, and have your
shared variable be an instance variable. Your two functions abc() and
abcd() would then be methods of that class.
 
B

Bruno Desthuilliers

Ivan Shevanski a écrit :
Alright heres my problem. . .Say I want to carry over a variable from
one function to another or even another run of the same function. Is
that possible? Heres a quick example of what I'm talking about.

def abc():
x = 1
y = x + 1
print y

def abcd():
y = x + 1
print y

abc()
abcd()

the output would be:


Traceback (most recent call last):
File "(stdin)", line 1, in ?
File "(stdin)", line 2, in abcd
NameError: global name 'x' is not defined



See, I want y in the second function to equal 4, carrying the x from the
first function over to the next. Is there any way to do this?

Actually, there are at least 3 ways to do it.

1/ Dirty solution:
------------------
x = 0
def abc():
global x
x = 1
print x + 1

def abcd():
global x
print x + 1


2/ functional solution:
-----------------------
def make_funcs():
x = 0
def _abc():
x = 1
return x + 1
def _abcd():
return x + 1
return _abc, _abcd

abc, abcd = make_funcs()
print abc()
print abcd()


3/ OO solution:
---------------
class Foo(object):
def __init__(self):
self._init_x()

def _init_x(self):
self._x = 1

def abc(self):
self._init_x()
return self.abcd()

def abcd(self):
return self._x + 1

f = Foo()
print f.abc()
print f.abcd()


Now guess which are:
A/ the pythonic solution
B/ the worst possible solution
C/ the most arcane solution

!-)
 
P

Peter Otten

Bruno said:
2/ functional solution:
-----------------------
def make_funcs():
x = 0
def _abc():
x = 1
return x + 1
def _abcd():
return x + 1
return _abc, _abcd

abc, abcd = make_funcs()
print abc()
print abcd()

The x in function _abc() is not the same as that in make_funcs() and _abcd()
as you can easily verify by modifying _abc() to

def _abc():
x # raises UnboundLocalError
x = 1
return x + 1

Once a variable is assigned a value the compiler treats it as local to that
function. Closed-over variables are therefore always read-only, much to the
chagrin of Lisp-lovers.

Peter
 
B

bruno modulix

Peter said:
Bruno Desthuilliers wrote:




The x in function _abc() is not the same as that in make_funcs() and _abcd()
as you can easily verify by modifying _abc() to

def _abc():
x # raises UnboundLocalError
x = 1
return x + 1

Once a variable is assigned a value the compiler treats it as local to that
function. Closed-over variables are therefore always read-only, much to the
chagrin of Lisp-lovers.

Doh :(

I wasn't aware of this limitation (I thought I had done this before in
Python and it was working, but it seems that I suffer a severe case of
MemoryCorruption...).

And this will also teach me to *always* test my code before posting (I
usually do...).

<op>
Sorry, my bad :(
</op>

<peter>
Thanks for the correction
</peter>

--
bruno desthuilliers
ruby -e "print '(e-mail address removed)'.split('@').collect{|p|
p.split('.').collect{|w| w.reverse}.join('.')}.join('@')"
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in '(e-mail address removed)'.split('@')])"
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top