5

I'd like to init a class from data stored in a simple python file specified while calling the script. The config file named myconfig.py is :

str='home'
val=2
flt=7.0

I'd like to call it during class initilization like so. One of the objectives is to define variable types as well in the file. I know of the configparser, but this method less verbose if it can be made to work.

class ClassInit(object):
    def __init__(self, configFile):
        fp, path, des = imp.find_module('',configFile)
        imp.load_module(configFile, fp, path, des)
        self.__dict__ = configFile.__dict__
        fp.close()

    def printVal(self):
        print '%s %0.2f'%(self.str, self.val)

if __name__ == '__main__':
    srcDir = 'src/'
    config = osp.join(srcDir, argv[0]) # config for current run 
    ci = ClassInit(config)
    ci.printVal()

Is anything like this possible?

3
  • 1
    You probably need to do mymod = imp.load_module(...), then use mymod.__dict__. Commented May 3, 2011 at 21:40
  • I had trouble getting started with load_module. How would this work in practice? Commented May 3, 2011 at 23:30
  • I don't quite understand what you mean. load_module returns the module object it has loaded. Commented May 4, 2011 at 16:22

2 Answers 2

2

Well, there are several ways to do this. The easiest way would be to use eval() or exec to evaluate this code within the class scope. But that's also the most dangerous way, especially if these files can be created by someone other than you. In that case, the creator can write malicious code that can pretty much do anything. You can override the __builtins__ key of the globals dictionary, but I'm not sure if this makes eval/exec entirely safe. For example:

class ClassInit(object):
    def __init__(self, configFile):
        f = open(configFile)
        config = f.read()
        f.close()
        config_dic = { '__builtins__': None}
        exec 'a = 4' in config_dic
        for key, value in config_dic.iteritems():
            if key != '__builtins__':
                setattr(self, key, value)

This method kills the unsafe 'builtins' object, but it's still not quite safe. For instance, the file may be able to define a function which would override one of your class's functions with malicious code. So I really don't recommend it, unless you absolutely control thos .py files.

A safer but more complex way would be to create a custom interpreter that interprets this file but doesn't allow running any custom code.

You can read the following thread, to see some suggestions for parsing libraries or other safer alternatives to eval(): Python: make eval safe

Besides, if all you ever need your config.py file for is to initialize some variables in a nice way, and you don't need to be able to call fancy python functions from inside it, you should consider using JSON instead. Python 2.6 and up includes simplejson, which you can use to initialize an object from file. The syntax is Javascript and not Python, but for initializing variables there's little difference there.

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

1 Comment

this works ! I"m creating the dictionary, so, I don't really need to worry about malicious code execution yet.
0

Can you try self.__dict__.update(configFile.__dict__)? I don't see why that wouldn't work.

3 Comments

says str object has no dict
It didn't work because configFile is a string containing the config file name, not a module object with a dict.
Apologies, I need to read the code a little better before I comment ^_^

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.