1

I have a file test.py:

import logging

def func():
    logger.info('some info')

if __name__ == '__main__':
    logger = logging.getLogger()
    func()

Which runs well. When I from test import func in another file and call the func() method, it gives me global name 'logger' is not defined error.

from test import func
def another_fun():
    func()

Even if I put logger = logging.getLogger() in another_func() before calling func(), it still gives me such error. I'm wondering in situations like this, what is the standard way of importing functions from other files with proper initialization. Thanks a lot.

J Freebird
  • 3,664
  • 7
  • 46
  • 81
  • I think that the `func()` is not recognizing `logger` as a global variable because you didn't told it to do it. Have you tried adding a `global logger` line before? Take a look at this: http://stackoverflow.com/questions/423379/using-global-variables-in-a-function-other-than-the-one-that-created-them – tomasyany Jun 23 '15 at 01:34
  • it is because you define `logger` in your `main` section, so it is never imported. – Christopher Pearson Jun 23 '15 at 01:35

2 Answers2

1
#!/usr/bin/env python3
import logging
logger = logging.getLogger("funclogger") # all modules importing this get access to funclogger log object

def func():    
    logger.info('some info')

if __name__ == '__main__':
    func()

Other process calling another_func():

#!/usr/bin/env python3
import logging
logger = logging.getLogger("funclogger") # May not be needed if this module doesn't log
from test import func

def another_fun():
    func()

It's as @Kevin mentioned.

another_fun() calls the method in test.py, but since your logger variable is ONLY initialized when you run it as a script (that's the __main__ portion), it's NOT initialized when func() is called and therefore can not recognize the variable. That also means when another_fun() calls func(), no logger object is found since another_fun() doesn't call __main__ in your test.py module.

NuclearPeon
  • 5,743
  • 4
  • 44
  • 52
  • Yes, I did import loging. And I did put name parameter in getLogger(), I'm sorry that I just omitted it here for simplicity. Now I put logger initialization under func(), but it still gives me "NameError: global name 'logger' is not defined". I don't get it why I should put it in both methods. – J Freebird Jun 23 '15 at 01:46
  • In case of race conditions, or if another module imports yours but important objects are defined in other modules. Basically it helps when threading or multiprocessing is involved and is sort of a best practice thing. It's not required, but recommended. If logger isn't defined, then it seems your logger object isn't initialized or is out of scope – NuclearPeon Jun 23 '15 at 01:48
  • I am also not getting any errors when I run your code, copy pasted, made executable, and including a hashbang. Are you running on linux and how are you executing your scripts? Edit: Correction: found your error – NuclearPeon Jun 23 '15 at 01:50
  • @JFreebird sorry for confusing you with the logger naming. I work with multiple processes and logging modules so it's something I highly recommend. Anyway, check the updated answer. – NuclearPeon Jun 23 '15 at 01:56
  • I see the problem. How should I solve it then? I did put the logger initialization under func(), but I still get the same error. I'm actually using Celery. another_func() is run by different processes at the same time. – J Freebird Jun 23 '15 at 06:18
  • If I recall correctly, processes do not share memory with each other, threads do. Going by what you told me, I would definitely recommend initializing the logger object in your `another_func()` method and as mentioned before I edited my answer for brevity, use a shared name between loggers. Does `another_func()` even call any logging methods via logger object? If `func()` is the only object that calls the logger, I am confused as to how you are getting the same error. Please update your answer with your traceback (stack trace) when you get the chance. – NuclearPeon Jun 23 '15 at 19:10
0

Don't initialize things in if __name__ == '__main__'. That's for the code that will run when your file is executed as a script. Ideally, it should consist of a single function call and nothing else.

You can't define globals in a different module, either. Each module has its own separate set of globals. You have to initialize logger in the test.py module.

Kevin
  • 28,963
  • 9
  • 62
  • 81
  • If I just want to import a function from that module, how can I initialize the variable? Put them before the function definition? – J Freebird Jun 23 '15 at 01:47