9

I have 2 files main.py and irc.py.
main.py

import irc
var = 1
func()

irc.py

def func():
    print var

When I try to run main.py I'm getting this error

NameError: global name 'var' is not defined

How to make it work?

@Edit
I thought there is a better solution but unfortunately the only one i found is to make another file and import it to both files
main.py

import irc
import another
another.var = 1
irc.func()

irc.py

import another
def func():
    print another.var

another.py

var = 0

5 Answers 5

11

Don't. Pass it in. Try and keep your code as decoupled as possible: one module should not rely on the inner workings of the other. Instead, try and expose as little as possible. In this way, you'll protect yourself from having to change the world every time you want to make things behave a little different.

main.py

import irc
var = 1
func(var)

irc.py

def func(var):
    print var
4
  • 1
    It would be easier for me to move this function to main file instead of adding this argument
    – gr56
    Commented May 15, 2011 at 21:56
  • @gr56: Then it sounds like refactoring is in order. If that's not possible either, I'd go with your solution of a third module which contains just the var object and is imported by both. If that works for you, please post it as an answer to your own question and accept it. Commented May 16, 2011 at 17:06
  • @SamirTalwar You can do this for functions, what about for instantiation of classes? For example, you want to define instances of a class in another module which you can import. The arguments can't be placeholders in this case.
    – Allen Wang
    Commented Jul 12, 2017 at 15:37
  • It works for me only when I execute irc.py earlier (run script). I use Python 3 and Spyder. If not I get name func is not defined.
    – Peter.k
    Commented Nov 21, 2017 at 20:43
9

Well, that's my code which works fine:

func.py:

import __main__
def func():
    print(__main__.var)

main.py:

from func import func

var="It works!"
func()
var="Now it changes!"
func()
2
4

Two options.

from main import var

def func():
    print var

This will copy a reference to the original name to the importing module.

import main

def func():
    print main.var

This will let you use the variable from the other module, and allow you to change it if desired.

7
  • 2
    Oh, this is just wrong. Mutual imports give me the heebie jeebies. Commented May 15, 2011 at 21:32
  • Then you just don't know what you're doing. Mutual imports are perfectly safe, and work fine given certain very clear restrictions. Commented May 15, 2011 at 21:33
  • @Ignacio: And they'll work fine in this toy code designed to highlight the problem. I have doubts they'll work as expected in the real thing. Even if they do, they will encourage fuzzy lines between modules which serve only to make adding new features and maintaining the old ones so much more difficult than it has to be. I can't imagine a situation where mutual imports work better than a third module that serves the original two. Commented May 15, 2011 at 21:35
  • This would be the best option for me but it gives me an error: AttributeError: 'module' object has no attribute 'func'
    – gr56
    Commented May 15, 2011 at 21:52
  • 1
    @gr56: It should be __main__ instead of main
    – Kabie
    Commented May 15, 2011 at 22:00
0

Well, var in the function isn't declared. You could pass it as an argument. main.py

import irc
var = 1
func(var)

irc.py

def func(str):
    print str
0

What Samir said works for Python 2

For python 3 you need to do it this way.

main.py

import irc
from irc import func

var = 1
func(var)
irc.py

irc.py

def func(var):
    print(var)

Not the answer you're looking for? Browse other questions tagged or ask your own question.