0

Say I'm storing settings in a Python file, like so:

#!/usr/bin/env python
#
# settings.py

import os

LOG_DIR = '/tmp'
LOG_FILE_MAIN = os.path.join(LOG_DIR, 'main.log')

Now, I include that file like so and change one of the values:

#!/usr/bin/env python
#
# main.py

import settings

settings.LOG_DIR = '/home/myuser'

When I print out a variable that relies on a (now changed) "reference" variable, I'll see that the value hasn't changed.

print(settings.LOG_FILE_MAIN)

Will return:

/tmp/main.log

Instead of:

/home/myuser/main.log

I understand why this is (Python has already calculated the strings value), but I need to work around it. Is there a way to achieve the desired result, other than creating a class and overriding the __setattr__ function?

4
  • You could use a dictionary of values instead of just a string. Commented Oct 14, 2014 at 16:46
  • This has nothing to do with the fact that strings are immutable. Commented Oct 14, 2014 at 16:54
  • Indeed, it does not. My mistake. Commented Oct 14, 2014 at 16:59
  • stackoverflow.com/questions/880530/… Commented Oct 14, 2014 at 18:40

1 Answer 1

1

Python has already executed the expression setting LOG_FILE_MAIN, and won't set it again just because you changed one of the inputs. The result of the expression is stored, not the expression itself.

You'll have to manually set the other variable again, or calculate it with a function at a later point, provided it is always to be calculated from LOG_DIR. E.g. LOG_FILE_MAIN should not be part of your settings, but always be calculated from settings as needed. I prefer low-tech approaches like that over the alternatives, which do require you to override the __setattr__ function, or otherwise handle all key attributes as setters.

Another approach is to use formatting operations; define LOG_FILE_MAIN as a string that'll have the whole settings module applied as keyword arguments in a str.format() call:

LOG_FILE_MAIN = '{LOG_DIR}/main.log'

and then every time you need to use LOG_FILE_MAIN do:

settings.LOG_FILE_MAIN.format(**vars(settings))

optionally applying a dir separator translation step to that too to make it platform-specific.

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.