0

I have the following file structure in my Python project:

Main.py
classes
  |--- __init__.py
  |--- Common.py
  |--- Logger.py
  |--- Dictionary.py

I'm setting a static variable of the Common class from within my Main file:

from classes.Common import Common

# set path to the log file for log output
Common.set_log_file_path(C:\\logging\\output.txt"))

which gets set in the Common class:

class Common():
    log_file_path = ''

    @staticmethod
    def set_log_file_path(log_file_path):
        Common.log_file_path = log_file_path

Now I instantiate a Logger object from within my Main file:

from classes.Logger import Logger

# initiate logger
log = Logger()

The Logger object reads the log file path from the Common object which works fine:

from Common import Common

class Logger():
    log_file_path = ''

    def __init__(self, log_file_path=''):
        # if not specified, take default log file path from Common class
        if log_file_path == '':
            self.log_file_path = Common.log_file_path

Now comes the problem: From my Main file I instantiate a Dictionary object:

from classes.Dictionary import Dictionary

# load dictionary
dictionary = Dictionary()

In the dictionary object I also want to have a logger, so I create one there:

from Logger import Logger

class Dictionary():
    log = Logger()

    def __init__(self):
        Dictionary.log.info('Dictionary > __init__()')

But this one doesn't work. Somehow when the Logger from within the Dictionary tries to load the log file path from the Common class, it is empty.

Why is that so? Shouldn't that be the same Common class and therefore holding the same static information here? Am I missing something? Do I do the imports in a wrong way?

I'm working with Python 2.6.5, and my imports are as follows:

Main.py imports Dictionary, Logger, Common
Dictionary.py imports Logger
Logger.py imports Common
Common has no imports
2
  • Did you set the path before importing Dictionary? Code that depends on the import order or expects some code to run before import is a nightmare to debug and maintain. Also make sure you don't have circular imports. Having class level fallback attributes is a nice hack but IMHO also exactly that: a hack. Commented May 12, 2015 at 14:14
  • I have all includes Java like at the top before any other code - therefore I think that should be fine. I added my import structure to the question - also no circular imports. Commented May 12, 2015 at 14:41

1 Answer 1

1

Almost everything in a Python module is dynamically executed — including import and class statements.

When you import the Directory module the first time the module is executed which means the import statement which imports Logger is executed and after the Logger is imported the class Directory: is executed which instantiates a Logger object. At this point your Common.set_log_file_path() was not yet called so that Logger object takes the default value which is defined when class Common: was executed.

The ”solution” would be importing Common and set the default path before executing anything that actually uses that default path attribute:

from classes.Common import Common
Common.log_file_path = 'C:/logging/output.txt'
from classes.Directory import Directory
from classes.Logger import Logger

Solution in quotes because having imports depending on other code being executed before is something that can turn into little nightmares very easily. Therefore it is something very seldom seen in productive code.

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.