-1

I know this has been explained here before, but I still cannot figure it out for my scenario, which I explain as simple as this:

def func1 ():
  a = 1
  b = 2
  print a + b

def func2 ():
  c = 3
  d = 4
  e = a * c
  f = b + d

func1()
func2()

When run like this:

$ ./test1.py 
3
Traceback (most recent call last):
  File "./test1.py", line 18, in <module>
    func2()
  File "./test1.py", line 14, in func2
    e = a * c
NameError: global name 'a' is not defined

Simple question is, how to change above code so func2 stores variables from func1?

Viktor
  • 83
  • 8
  • Have a read of http://learnpythonthehardway.org/book/ex21.html and possibly the earlier chapters too – YXD Jul 27 '15 at 22:04

4 Answers4

5

Rather than make the variables global as mentioned in the other answers, I would return them in func1 and consume them in func2.

def func1():
    a = 1
    b = 2
    print a + b
    return a, b

def func2(a, b):
    c = 3
    d = 4
    e = a * c
    f = b + d

func2(*func1())

As we are returning multiple variables in func1() these come as a tuple (a, b).

Rather than pass this as a single variable to func2 we must unpack them into 2 variables.

Here is an excellent question and answer on the subject of *args **kwargs.

Community
  • 1
  • 1
Ewan
  • 14,592
  • 6
  • 48
  • 62
  • That is what I was looking for! I missed the crutial part, returning variables on the end of the function. Can I ask what that asterix does in func2(*func1())? – Viktor Jul 27 '15 at 22:17
  • @Viktor - updated my answer and linked to a much better explanation to help you – Ewan Jul 27 '15 at 22:20
  • thanks a lot. One more problem. if I define third variable that does not come from func1, eg. func2 (a, b, g): and call it based on your code, func2(*func1(), 5), I get error: SyntaxError: only named arguments may follow *expression. – Viktor Jul 27 '15 at 23:11
  • @Viktor - it's not a wildcard (looking at your comment on the other answer). If you wanted to add more arguments you just add them before the unpacking. e.g. `func2(g, a, b)` and `func2(5,*func1())`. – Ewan Jul 28 '15 at 09:18
3

The right way to do this is with return and parameters.

def func1 ():
  a = 1
  b = 2
  return a,b

def func2 (a, b):
  c = 3
  d = 4
  e = a * c
  f = b + d

a, b = func1()
print(a, b)
func2(a, b)

Result:

>>> a, b = func1()
>>> print(a, b)
1 2
>>> func2(a, b)
TigerhawkT3
  • 48,464
  • 6
  • 60
  • 97
  • I lost some reputation points on this question, but I've learnt something here! Just realized that your solution allows me to add a third argument as both variables are "exported" from the func1, unlike as solution from Ewan who uses unpacking with wildcards, but that can have some easy solution as well, not sure. – Viktor Jul 27 '15 at 23:46
  • That's not a wildcard; it's a special operator that (in this context) unpacks an iterable. It will unpack everything automatically, handling two arguments just as easily as three [or more](http://stackoverflow.com/questions/36901/what-does-double-star-and-star-do-for-python-parameters). You just have to make sure the arguments you're providing match the other function's parameters. – TigerhawkT3 Jul 27 '15 at 23:49
0
a = 1
b = 2
def func1 ():
    print a + b

def func2 ():
    c = 3
    d = 4
    e = a * c
    f = b + d

func1()
func2()
mlwn
  • 1,156
  • 1
  • 10
  • 25
0

Just made the variable global (without this, a and b are only local variables):

def func1 ():
  global a, b
  a = 1
  b = 2
  print a + b

def func2 ():
  c = 3
  d = 4
  e = a * c
  f = b + d

func1()
func2()

But better avoid this solution

Clodion
  • 1,017
  • 6
  • 12