1

I have the following code in Python:

myFile = open("Test1.py", "w")
myFile.write("def foo():\n\tprint('hello world!')") #defining foo in the module Test1
myFile.close()
import Test1

Test1.foo() #this works great

myFile = open("Test1.py", "w")
#replace foo() with foo2() and a new definition
myFile.write("def foo2():\n\tprint('second hello world!')") 
myFile.close()

import Test1 #re-import to get the new functionality

Test1.foo2() #this currently throws an error since the old functionality is not replaced

I would like it if when I re-imported Test1, the functionality of foo2() replaced foo(), and the program would print "second hello world!" at the end.

The best solution I could find was to "de-import" the module, which looks potentially dangerous, and also seems unnecessary (I haven't tried it yet).

What would be the best way to get the new functionality of foo2() into the program?

Community
  • 1
  • 1
Pro Q
  • 4,391
  • 4
  • 43
  • 92
  • 3
    .....why are you doing this? – NightShadeQueen Jul 22 '15 at 21:09
  • This is probably a terrible idea, and something you should never do unless the entire point is messing around with python's importing, but see `reload` (python 2) and [`imp.reload` (python 3)](https://docs.python.org/3.1/library/imp.html). – NightShadeQueen Jul 22 '15 at 21:10
  • Note that what `reload` does is that it basically goes over, finds the file, and `exec`s it. There's all sorts of corner cases it doesn't handle. Again. Don't do this, why are you doing this, what are you trying to do, this is a terrible idea. – NightShadeQueen Jul 22 '15 at 21:12
  • @NightShadeQueen I'm trying to write a "Programming Helper" where you can define functions for it, and it can run these functions later in a specified order. (These functions should also be accessible after the program is done running). The easiest way I could think of to store and access these functions was by putting them in another module/file, and having it use the definitions from there. – Pro Q Jul 22 '15 at 22:04
  • Fun fact: `foo.__code__` in python is *mutable* :P – NightShadeQueen Jul 22 '15 at 22:19
  • @NightShadeQueen I am curious and google didn't reveal much. Can you tell me the reasoning behind mutability of `__code__`? Or some good use case? – Akshat Harit Jul 22 '15 at 22:27
  • see: https://www.youtube.com/watch?v=H2yfXnUb1S4 ("Don't Do This", Richard Jones, pycon 2013) – NightShadeQueen Jul 22 '15 at 22:29
  • @NightShadeQueen I watched up to 7:39, and I still don't see how I could use the mutability of `__code__` to save the definitions of functions in a way such that they can be accessed even after my program is done running without using a file. I would also like the definitions to be human-readable, if that makes a difference. – Pro Q Jul 22 '15 at 22:55

1 Answers1

2

It seems like you would want to use the reload keyword, like so:

>>> reload(Test1)
Blair
  • 6,623
  • 1
  • 36
  • 42
  • it's no longer a standard function in python >=3.4, it is a method in 'importlib' so you have to import it from importlib first. – Peter Tillemans Jul 22 '15 at 21:13
  • I tested it out as the question seemed interesting, and on Python 2.7 I am not getting the new(er) module loaded, even after reload. Can you check the output of dir(Test1) and check if it changed? – Akshat Harit Jul 22 '15 at 21:27
  • On further investigation, I had to add os.remove("Test1.pyc") to remove the pyc file so that reload was successful. Also interestingly, the reloaded module still has the original function along with foo2. Can you confirm this behavior? – Akshat Harit Jul 22 '15 at 21:31
  • @AkshatHarit But if I overwrite foo with a new definition, it uses the new definition, not the old one. – Pro Q Jul 22 '15 at 22:14
  • @ProQ Did you also need os.remove to remove the original .pyc? I think pyc files are generated when the timestamp of py is newer. Due to the short time nature of the program, it seems the time stamp doesn't change. So I had to remove the .pyc file. – Akshat Harit Jul 22 '15 at 22:20
  • @AkshatHarit Yes I did; it did not work without `os.remove("Test1.pyc")`. – Pro Q Jul 22 '15 at 23:00