2

Im trying to import a module using exec statement but it fails,

code.py

def test(jobname):
    print jobname
    exec ('import ' + jobname)

if __name__ = '__main__':
  test('c:/python27/test1.py')

Error: Syntax error:

import:c:\python27 est1.py

user1050619
  • 19,822
  • 85
  • 237
  • 413
  • not sure why there is spaces, if you notice the paramter that I pass there is no spaces – user1050619 Oct 22 '12 at 20:51
  • 1
    I'm willing to bet this is not your actual code, and if you paste this into an interpreter or a script it gives a different error. What you're actually asking it to do is `import c:/python27/test1.py` (no quotes, a path rather than a module name, etc.), which is bogus and will give a SyntaxError, but not this one. Your actual code probably uses backslashes instead of slashes, and doesn't escape the `\t`, which is why you get this particular error. – abarnert Oct 22 '12 at 20:57
  • Probably what you mean is [python - How to import a module given the full path? - Stack Overflow](https://stackoverflow.com/questions/67631/how-to-import-a-module-given-the-full-path) – user202729 Oct 24 '21 at 01:12

4 Answers4

4

You probably mean execfile(jobname). And import does not work with filenames. It works with package names. Any good tutorial would cover that. Another issue would be the \t being interpreted as a tab character, but here it is not the case because you are uaing forward slash not baclslash...

jadkik94
  • 7,000
  • 2
  • 30
  • 39
  • `execfile` isn't the same thing as `import. – abarnert Oct 22 '12 at 23:04
  • @abarnert Yeah sure. But from what I understood from the code he posted, this is the intended usage of `exec(import ...)`. – jadkik94 Oct 23 '12 at 06:25
  • Nothing that would work after `exec("import foo")` (e.g., `print(foo.myfunc(foo.myconst))`) is going to work after `execfile("foo.py")`. So it can't be the intended usage. It's possible that he could rewrite all of his code to work differently (assuming there are no conflicting names between the modules, etc.), but if he's going to rewrite all of his code anyway, there are much better solutions. – abarnert Oct 24 '12 at 22:55
  • @abarnert Without more details, that's as close to what OP's code does as possible... Now what the purpose of it is, it's another issue... – jadkik94 Oct 25 '12 at 08:52
1

Somehow, I think you must be calling

test('c:\python27\test1.py')

instead of

test('c:/python27/test1.py')

The backslash in front of the t is being interpreted as a tab character. Thus the error

import:c:\python27 est1.py

Notice the missing t.

Secondly, the import command expects a module name, not a path. For importing, use __import__ not exec or execfile. execfile has been removed from Python3, so for future compatibilty, you may not want to use it in Python2. exec can be used instead, but there are problems with using exec.

Assuming c:\python27 is in your PYTHONPATH, you could do something like this:

def test(jobname):
    print jobname
    __import__(jobname)

if __name__ == '__main__':
    test('test1')
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
0
def test(jobname):
    print jobname
    a = jobname.split('/')
    b = "/".join(a[0:-1])
    c = a[-1][0:-3]
    sys.path.append(b)
    exec ('import ' + c)

if __name__ = '__main__':
  test('c:/python27/test1.py')

Try this code. Your path must be added to sys.path() variable.

Aniket Inge
  • 25,375
  • 5
  • 50
  • 78
  • This just clutters the PYTHONPATHtoo much and what if the eextension of the file is .pyc or .pyo ? – jadkik94 Oct 23 '12 at 10:40
  • he wants to run a .py file. One recipe for one problem man. @jadkik94 – Aniket Inge Oct 23 '12 at 11:09
  • @jadkik94: As written, `test` doesn't handle .pyc/.pyo (or .pyw, since this is Windows), and it also won't handle backslashes, and it probably has other problems, but it would be trivial to write a version without those problems, so the basic approach is sound (except for cluttering PYTHONPATH, which is a problem). – abarnert Oct 24 '12 at 19:54
  • @Aniket: Why are you using string manipulation instead of `os.path` methods? Besides being easier to read, harder to get wrong, and more pythonic, it would be more flexible. (Also, why would you write `[0:-3]` instead of `[:-3]`? They mean the same thing, but that just raises a red flag making me think I made a typo…) – abarnert Oct 24 '12 at 19:56
0

Im trying to import a module using exec statement

Don't do that.

First, do you really need to import a module programmatically? If you tell us what you're actually trying to accomplish, I'm willing to bet we can find the square hole for your square page, instead of teaching you how to force it into a round hole.

If you do ever need to do this, use the imp module; that's what it's for.

Especially if you want to import a module by path instead of by module name, which is impossible to do with the import statement (and exec isn't going to help you with that).

Here's an example:

import imp

def test(jobname):
    print jobname
    while open(jobname, 'r') as f:
        job = imp.load_module('test', f, jobname, ('.py', 'U', 1))

Of course this doesn't do the same thing that import test1 would do if it were on your sys.path. The module will be at sys.modules['test'] instead of sys.modules['test1'], and in local variable job instead of global variable test1, and it'll reload instead of doing nothing if you've already loaded it. But anyone who has a good reason for doing this kind of thing had better know how to deal with all of those issues.

abarnert
  • 354,177
  • 51
  • 601
  • 671
  • I have a system where we need to process multiple files on a daily basis..Each files needs to be processed 4 different ways. – user1050619 Oct 23 '12 at 02:55
  • Then you either need to redesign the way your code is organised and use `imp` or you can use execfile or use the subprocess package. Read more about each individually or ask about the in a different question. – jadkik94 Oct 23 '12 at 11:18
  • Everything @jadkik94 said is spot on. But there may be an even simpler answer. You've got a static set of four modules. Why do these need to be imported dynamically? Why not just `import test1; import test2; import test3; import test4`? (Even if you need to iterate over the modules, that's not a problem: just do `mymodules = [test1, test2, test3, test4]`. You can even do this dynamically as `mymodules = [sys.modules[module] for module in sys.modules if module.startswith('test')`. – abarnert Oct 24 '12 at 22:58
  • This solution worked for me as well as additionally: `test = eval(f'test_module.{class_name}')()` – MathCrackExchange Jan 29 '22 at 17:57