1

Code is much more precise than English; Here's what I'd like to do:

import sys

fileName = sys.argv[1]
className = sys.argv[2]

# open py file here and import the class
# ???

# Instantiante new object of type "className"
a = eval(className + "()") # I don't know if this is the way to do that.

# I "know" that className will have this method:
a.writeByte(0x0)

EDIT:

Per the request of the answers, here's what I'm trying to do:

I'm writing a virtual processor adhering to the SIC/XE instruction set. It's an educational theoretical processor used to teach the fundamentals of assembly language and systems software to computer science students. There is a notion of a "device" that I'm trying to abstract from the programming of the "processor." Essentially, I want the user of my program to be able to write their own device plugin (limited to "read_byte" and "write_byte" functionality) and then I want them to be able to "hook up" their devices to the processor at command-line time, so that they can write something like:

python3 sicsim -d1 dev1module Dev1Class -d2 ...

They would also supply the memory image, which would know how to interact with their device. I basically want both of us to be able to write our code without it interfering with each other.

3
  • Based on your comments, it sounds suspiciously like you are avoiding importing whatever fileName is because you don't want some of the top level code to run; too bad, you cannot do that! But there are other options, and if you show us some more of your code I'm sure we can show you how, probably by refactoring the "to be imported" fileName Commented Apr 8, 2012 at 1:16
  • I edited my question to explain my situation more fully. Commented Apr 8, 2012 at 2:56
  • based on what you've stated, your general approach for implementing plug-ins seems reasonable. Other python programs that have similar designs still require that the whole file be loaded normally. Commented Apr 8, 2012 at 4:07

2 Answers 2

2

Use importlib.import_module and the built in function getattr. No need for eval.

import sys
import importlib

module_name = sys.argv[1]
class_name = sys.argv[2]

module = importlib.import_module(module_name)
cls = getattr(module, class_name)

obj = cls()
obj.writeByte(0x0)

This will require that the file lives somewhere on your python path. Most of the time, the current directory is on said path. If this is not sufficient, you'll have to parse the directory out of it and append it to the sys.path. I'll be glad to help with that. Just give me a sample input for the first commandline argument.

Valid input for this version would be something like:

python3 myscript.py mypackage.mymodule MyClass
Sign up to request clarification or add additional context in comments.

3 Comments

Is it the case that the importlib module words sort of like importing individual items (I'm not sure if "items" is the correct technical term, but bear with me) from a module, but using an exec() approach would be like import * ? I would imagine that the former approach is safer so that you don't overwrite your own variables and such.
@WordsLikeJared. Neither approach is like import * and neither will overwrite your variables. Both will execute the whole file. Is there some reason that this is bad? If the file is written in a standard way, only definitions will run when it's imported as code that actually changes state beyond that will be guarded by a line like if __name__=='__main__':.
only the import statement will alter your own module or function namespace, the functions in importlib always return module or python objects, which is why there is an assignment to module here.
1

As aaronasterling mentions, you can take advantage of the import machinery if the file in question happens to be on the python path (somewhere under the directories listed in sys.path), but if that's not the case, use the built in exec() function:

fileVars = {}
exec(file(fileName).read(), fileVars)

Then, to get an instance of the class, you can skip the eval():

a = fileVars[className]()

3 Comments

Would code outside class definitions be executed if I did that?
@WordsLikeJared Code outside the class definitions will be executed with both approaches proposed.
@Words Like Jared: If you need that functionality, you're probably trying to solve the wrong problem. maybe you should tell us a bit more about what you are trying to do.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.