python 3.x - access (read-only) global variable within class method -
i have class config() loads configuration options. create instance of class named cfg.
have many classes a, b, c have read only members cfg.
from mylib.config import * mylib.a import * mylib.b import * mylib.c import * cfg = config(filename) = a() a.do_things()
and instance in constructor have:
def __init__(self): self.name = cfg.name
problem @ runtime "nameerror: name 'cfg' not defined" on line self.name = cfg.name
i first thought it's import mylib.a, mylib.b , mylib.c before declaring cfg moved
cfg = config(filename)
before importing mylib.a...b...c. still same error.
possible solutions:
1. pass object 'cfg' argument, have change signature methods in classes a, b, c , feel it's not clean since multiplies same argument accross methods.
2. create private member _cfg classes a, b, c. better nor nice again, data multiplied
3. put class definition + instance declaration in 1 file, , import in mylib.a, mylib.b , mylib.c : afaisi it's best solution, still not taste because mix class definition , instance declaration, , have class definitions in class files
4. avoid class definition , instanciation in same file, can create 'init.py'
from mylib.config import * cfg = config(filename)
and import init in mylib.a, mylib.b , mylib.c... have init file, log functions , since config constructor uses function, creates circular import issues (init.py imported in mylib.config.py class declaration file, , mylib.config imported in init.py), avoid should have init.py , init_config.py instance.
isn't there better/cleaner/simplier ?
how about, within mylib.config
, create initialize
function, creates global configuration object.
config_obj = none #todo: pick better name class config: def __init__(self, filename): pass #todo: definition goes here. def initialize(filename): global config_obj config_obj= config(filename)
then, within main file, call function before modules b or c.
from mylib.config import * mylib.a import * mylib.b import * mylib.c import * initialize(filename) = a() a.do_things()
don't forget import config
in whatever modules need refer config_obj
.
#mylib.a import config class whatever: def __init__(self): self.name = config.cfg_obj.name
note shouldn't replace import config
from config import *
, because a's copy of cfg_obj
won't updated when main file calls initialize
.
if don't class modules having functions or global variables, can make initialize
static method of config class, returns singleton instance of config.
#singleton config class. 1 instance of should ever exist. #users, please don't call config(filename). use get_instance() instead. class config: instance = none def __init__(self, filename): pass #definition goes here... @staticmethod def initialize(filename): if config.instance not none: msg = "singleton config has been initialized" raise exception(msg) #this place config(filename) should ever called. config.instance = config(filename) return config.instance @staticmethod def get_instance(): if config.instance none: msg = "can't instance because hasn't been initialized yet" raise exception(msg) return config.instance
(there may better ways make singleton in python. went simple approach illustrative purposes.)
then initialize in main file:
from mylib.config import * mylib.a import * mylib.b import * mylib.c import * config.initialize(filename) = a() a.do_things()
and instance in modules:
#mylib.a import config class whatever: def __init__(self): self.name = config.config.get_instance().name
(with approach, think you're able from config import *
in modules if like.)
Comments
Post a Comment