symbol has wrong value after import - python

I have one python file which is responsible for optionparsing, setting up some stuff and then starting the gui.
The gui itself and some helper functions are in another python file.
file1.py:
myConf = None
if __name__ == "__main__":
confFileName = HOME+"/test/.conf"
myConf = Config()
print(myConf) # works as expected
run() # this starts the gui
file2.py
from file1 import myConf
...somestuff...
def on_clicked( self, widget ):
mappings = myConf.GetMappings()
As soon as the on_clicked callback is triggered I get an exception:
AttributeError: 'NoneType' object has no attribute 'GetMappings'
This means the myConf which is used in file2 is not yet initialized.
However, the gui is set up AFTER myCOnf has been initialized in file1.
I want myConf to be a global object which stores information which then every other file can access during runtime.
Whats wrong? Why is it not working as intended?
Has file2 its own copy of the symbol whoch has not been initialized?

When you run file1.py directly, the code under __name__ == "__main__" is executed, initializing myConf and working as expected. However, when you do from file1 import myConf, file1.py is not the main script and, therefore, leaves myConf at the None that it was initialized to. Therefore, when you import myConf, its value is None and raises the error that the None has no attribute getMappings. It doesn't have this attribute, so the error is meant to be raised.
To fix this, you need to move the initializing script out of the if __name__ == "__main__". This leaves your script looking like this:
myConf = None
confFileName = HOME+"/test/.conf"
myConf = Config()
if __name__ == "__main__":
print(myConf)
run() # this starts the gui

Related

Python relative import variable name error [duplicate]

I created two files, and when I run a.py, result is {'1': '1'}, it's correct. however, running b.py, the result is none. How can I get the value of requests from b.py?
a.py:
requests = {}
def set_value():
global requests
requests["1"] = "1"
if __name__ == "__main__":
set_value()
print(requests)
b.py:
import a
def get_value():
print(a.requests)
if __name__ == "__main__":
get_value()
if __name__ == "__main__": means that the code following it will only be executed when the file is called explicitly with python3 filename.py from the command line. Since you are simply importing your file and not executing it, the global variable is never set.
Also, python variables are all "global" variables when declared outside of a function, and the global keyword is only needed when you want to declare a global variable inside of a function.
To fix this, change a.py to the following:
requests = {}
def set_vale():
requests["1"] = "1"
set_vale()

how can I access a global variable from another .py file in python?

I created two files, and when I run a.py, result is {'1': '1'}, it's correct. however, running b.py, the result is none. How can I get the value of requests from b.py?
a.py:
requests = {}
def set_value():
global requests
requests["1"] = "1"
if __name__ == "__main__":
set_value()
print(requests)
b.py:
import a
def get_value():
print(a.requests)
if __name__ == "__main__":
get_value()
if __name__ == "__main__": means that the code following it will only be executed when the file is called explicitly with python3 filename.py from the command line. Since you are simply importing your file and not executing it, the global variable is never set.
Also, python variables are all "global" variables when declared outside of a function, and the global keyword is only needed when you want to declare a global variable inside of a function.
To fix this, change a.py to the following:
requests = {}
def set_vale():
requests["1"] = "1"
set_vale()

where to open and close file in web.py

A data file was getting corrupted when I terminated the program and realised that it was never properly closed.
It is quite critical that it does not get corrupted. So I added a statement to close the file.
Now, it seems like the file gets opened twice and then closed. That's one operation too many. There are of course many read-write operations in-between but it should only open and close the files once.
Here is what I have done to the standarize web.py template:
import web
import pandas as pd
store = pd.HDFStore('data_file.h5')
urls = (
'/', 'index'
)
class index:
def __init__(self):
self.__df = store['df']
def GET(self):
# several read-write, and modify operations on self.__df
return "Hello, world!"
if __name__ == "__main__":
try:
app = web.application(urls, globals())
app.run()
finally:
store.close()
Now, if I move the line which opens the store down inside the try statement at the bottom, it complains since it compiles the class but I can't find the variable store.
I tried initialising store with None at the top but it didn't work either. Then I tried putting that line up at the top in the function and calling it from the bottom, however, that didn't bring it into scope.
I was thinking of making it a global variable, which would probably do the trick, is that the right approach?
See web.py running twice. As mentioned there, avoid using globals as they don't do what you think they do... app.py runs twice, once on startup and a second time within web.appplication(urls, globals()). If you set autoreload=False in web.applications() call, it won't load the file twice.
Another solution is to attach your store to web.config, which is globally available.
if __name__ == "__main__":
try:
web.config.store = pd.HDFStore('data_file.h5')
app = web.application(urls, globals())
app.run()
finally:
web.config.store.close()
...and reference that global in your __init__
class index:
def __init__(self):
self.__df = web.config.store['df']

got AttributeError: 'module' object has no attribute while importing global variable from another file

I have two python files like this:
# first.py
global x
if __name__ == "__main__":
x = 'test_var'
and:
# second.py
import first
class XX(object):
#staticmethod
def print_x():
print first.x
I run this script:
import second
second.XX.print_x()
And I get this error:
AttributeError: 'module' object has no attribute 'x'
Any idea what's going wrong?
The code in first.py never runs because it isn't your entry point and the code isn't directly called, meaning x is never defined. Use first.py as your entry point or put the declaration of x into a method that you call before trying to access it.

Importing values in config.py

I wanted to mix a config.py approach and ConfigParser to set some default values in config.py which could be overridden by the user in its root folder:
import ConfigParser
import os
CACHE_FOLDER = 'cache'
CSV_FOLDER = 'csv'
def main():
cp = ConfigParser.ConfigParser()
cp.readfp(open('defaults.cfg'))
cp.read(os.path.expanduser('~/.python-tools.cfg'))
CACHE_FOLDER = cp.get('folders', 'cache_folder')
CSV_FOLDER = cp.get('folders', 'csv_folder')
if __name__ == '__main__':
main()
When running this module I can see the value of CACHE_FOLDER being changed. However when in another module I do the following:
import config
def main()
print config.CACHE_FOLDER
This will print the original value of the variable ('cache').
Am I doing something wrong ?
The main function in the code you show only gets run when that module is run as a script (due to the if __name__ == '__main__' block). If you want that turn run any time the module is loaded, you should get rid of that restriction. If there's extra code that actually does something useful in the main function, in addition to setting up the configuration, you might want to split that part out from the setup code:
def setup():
# the configuration stuff from main in the question
def main():
# other stuff to be done when run as a script
setup() # called unconditionally, so it will run if you import this module
if __name__ == "__main__":
main() # this is called only when the module is run as a script

Categories

Resources