On 6/9/2014 11:03 PM, Steven D'Aprano wrote:
On Tue, Jun 10, 2014 at 05:23:12AM +0300, Paul Sokolovsky wrote:

execfile() builtin function was removed in 3.0.

Because it was hardly ever used. For short bits of code, it is usually inferior to exec with a string in the file. For substantial bits of code, it is generally inferior to 'from file import *' and does not have the option of other forms of import. For startup code that you want every session, it is inferior to PYTHONSTARTUP or custom site module.

>> This brings few problems:
1. It hampers interactive mode - instead of short and easy to type
execfile("file.py") one needs to use exec(open("file.py").read())

If the amount of typing is the problem, that's easy to solve:

# do this once
def execfile(name):
     exec(open("file.py").read())

Another possibility is:

os.system("python file.py")


2. Ok, assuming that exec(open().read()) idiom is still a way to go,
there's a problem - it requires to load entire file to memory. But
there can be not enough memory. Consider 1Mb file with 900Kb comments
(autogenerated, for example). execfile() could easily parse it, using
small buffer. But exec() requires to slurp entire file into memory, and
1Mb is much more than heap sizes that we target.

Execfile could slurp the whole file into memory too. Next parse the entire file. Then execute the entire bytecode. Finally toss the bytecode so that the file has to be reparsed next time it is used.

There's nothing stopping alternative implementations having their own
implementation-specific standard library modules.
...
So you could do this:

from upy import execfile
execfile("file.py")

So long as you make it clear that this is a platform specific module,
and don't advertise it as a language feature, I see no reason why you
cannot do that.

If you want execfile as a substitute for 'python -i file' on the unavailable command console, you should have the option to restore globals to initial condition. Something like (untested)

# startup entries in globals in CPython 3.4.1
startnames={'__spec__', '__name__', '__builtins__',
        '__doc__', '__loader__', '__package__'}

def execfile(file, encoding='utf-8', restart=<True/False>):
  glodict = globals()
  code = open(file, 'r', encoding=encoding)
  # don't restart if the file does not open
  if restart:
    for name in list(glodict):
      if name not in startnames:
         del glodict(name)
  for statement in statements(code):  # statements is statement iterator
    exec(statement,...globals=glodict, locals=glodict)

--
Terry Jan Reedy

_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to