What Is an Alternative to Execfile in Python 3

What is an alternative to execfile in Python 3?

According to the documentation, instead of

execfile("./filename") 

Use

exec(open("./filename").read())

See:

  • What’s New In Python 3.0

Alternative to execfile in Python 3?

The 2to3 script replaces

execfile(filename, globals, locals)

by

exec(compile(open(filename, "rb").read(), filename, 'exec'), globals, locals)

This seems to be the official recommendation. You may want to use a with block to ensure that the file is promptly closed again:

with open(filename, "rb") as source_file:
code = compile(source_file.read(), filename, "exec")
exec(code, globals, locals)

You can omit the globals and locals arguments to execute the file in the current scope, or use exec(code, {}) to use a new temporary dictionary as both the globals and locals dictionary, effectively executing the file in a new temporary scope.

True alternative to exec() in python

Why not executing the command in the function and compose the filename using str.format instead of using exec ?

def all_installs_to_dataframe(month):
'''Imports csv's from different months to pandas dataframes'''
dataset = pd.read_csv('/path/file2017{}_overview.csv'.format(month), sep=',', header=0, encoding='utf-16')

How to execute a file within the Python interpreter?

Several ways.

  • From the shell

    python someFile.py
  • From inside IDLE, hit F5.

  • If you're typing interactively, try this (Python3):

    >>> exec(open("filename.py").read())
  • For Python 2:

    >>> variables= {}
    >>> execfile( "someFile.py", variables )
    >>> print variables # globals from the someFile module

Difference between import and execfile

There are many differences, but from your point of view the most significant is probably that import gives you more control over the namespace in which the objects defined in utils.py end up.

Let's consider three variants on import. The first is the one you asked about:

import utils
utils.f1()

utils is the only symbol that has been added to your workspace—any pre-existing f1 in your base workspace will not have been overwritten, and if there is none, then f1() on its own will not be recognized. For code I intend to maintain, I greatly prefer this way of importing, because it makes it easy for me to search my source file for all the places in which it depends on utils.

But if saying utils.f1() every time is too verbose then you can do this:

from utils import f1
f1()

Now if you say f1() that will call utils.f1(), because that is the code object that you have now associated with the name f1 in your workspace. It's now slightly harder to get an overview of where your code is reliant on the utils module. But at least this type of import statement gives you precise control over which symbols were imported and which not. You can even rename symbols during this process:

from utils import f1 as EffOne
EffOne()

Finally you can choose to lose control over the namespace entirely:

from utils import *

Now, who knows what symbols have been imported: basically everything that utils has to offer the world (or, if the utils developer took the trouble to specify an __all__ attribute, then everything listed there). I'd advise you to use import * only for quick-and-dirty programming, if at all.

This is actually the importing style that is closest to execfile from the namespace point of view: execfile('utils.py') does much the same as from utils import * in that it dumps all symbols defined by utils willy-nilly into your workspace. One slight difference is that execfile won't even limit itself to the symbols in __all__ if that is defined—in fact, the __all__ symbol itself will just get dumped in your lap along with everything else.

Beyond namespaces, there are still plenty of differences between from utils import * and execfile('utils.py'). One is caching: a second import call on utils will be very fast (the code will not be re-run), but a second call to execfile('utils.py') may take just as long as the first because the code will be re-run. Also, there may be some code (often test code) inside utils.py that the utils author does not want to run at import time, but only when the file is executed via execfile. Such code is placed inside an if __name__ == '__main__': clause.

Python3-Issue with calling exec(open().read()) inside a function

According to exec_documentation:

If exec gets two separate objects as globals and locals, the code will be executed as if it were embedded in a class definition.

Inside method globals() and locals() are different objects:

def method():
print(globals() == locals())
exec('X=10')
print('Method execution =', X)

method()

output:

False
NameError: name 'X' is not defined

In global level this objects are equal:

print(globals() == locals())
exec('X=99')
print('Global exec =', X)

Output:

True
Global exec = 99

So If you want to do it via method, you need to pass the same object to exec. For your code it would look like this:

def func_call(filename):
exec(open(filename).read(), globals(), globals())
print("X = %s" %X)

func_call("./init.py")

Nevertheless, as I mentioned in comment, create file with consts and import it. Try to avoid using exec/eval at all costs, unless you are 100% sure what you are doing.

Equivalent of source() of R in Python

Given 2 python scripts: first.py and second.py, the usual way to execute the first from the second is something in the lines of:

first.py:

def func1():
print 'inside func1 in first.py'

if __name__ == '__main__':
# first.py executed as a script
func1()

second.py:

import first

def second_func():
print 'inside second_func in second.py'

if __name__ == '__main__':
# second.py executed as a script
second_func()
first.func1() # executing a function from first.py

Edits:

  • You could also go for the simple execfile("second.py") if you wish (although it is only within the calling namespace).
  • And a final option is using os.system like so:

    os.system("second.py").


Related Topics



Leave a reply



Submit