Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
import vs inserting code
#1
is there any circumstance in which inserting code, such as while editing, has a different result than doing an import of the same code when both files are in the current directory/folder, over a range of possible code that could be different?
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#2
Perhaps I misunderstand the question / idea - or my knowledge of the language fails me, but let's try this:

alpha.py
x=5
from beta import *
print(x)
beta.py
x=7
del x
you see, it is not the same as copy-pasting beta.py contents instead of insert. the variable is as if shadowed rather than overrwritten. disclaimer: I don't understand the mechanics, just was amused by the question and tried few statements in two files
Gribouillis likes this post
Reply
#3
(Jun-14-2024, 01:18 AM)Skaperen Wrote: is there any circumstance in which inserting code, such as while editing, has a different result than doing an import of the same code
@rodiongork 's answer is excellent. When you import a module, this module's code is executed in the new module's namespace. When you insert code, it is executed in the namespace of the module where the code is inserted.

This can have unpredictable consequences. Variables can be shadowed (this also includes functions and classes), code depending on the module name could behave differently, for example if __name__ == '__main__' code, etc.
rodiongork likes this post
« We can solve any problem by introducing an extra level of indirection »
Reply
#4
gotcha on the differences. i can see what is happening. i wish there was a way to have a run-time insert operation that would have all the exact effects of doing an insert. my first thought is a wrapper around python itself, but this can be complicated, error prone, and create a confusing context.

i will need to go back and look at this in a source management context.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#5
Quote:i wish there was a way to have a run-time insert operation that would have all the exact effects of doing an insert.

what is your goal, if it may be asked?

I'm not sure, but exec behaves somewhat differently, may be it is closer to what you want to achieve? e.g. read the file to be "inserted" and
exec it, e.g.:

x = 5
exec('x=7\ndel x')
print(x) #throws x not defined
Reply
#6
(Jun-21-2024, 05:47 AM)rodiongork Wrote: what is your goal, if it may be asked?

the goal is to have that insert effect, such as doing stuff with the local namespace in ways where doing a common thing is the way, such as having the logic in multiple places that all still need to access the same local namespace. i just got done writing 6 different command scripts that each needed a lot of the same code. it would have been very awkward, at best. for the common code to be there just once and the difference code to be refactored to choose what to do based on which command i being run (yes, i have written command code that varies what it does based on the named it was run as, in Bash, C, and Python).

a function certainly should not access caller local namespace. but, in some cases, you need to work with local namespace in some common way in many places. it looks bad to have duplicate code; people end up looking to see how those chunks of code might be different. how can Python let you have just one copy of code, so that it is can be used in many places and is clear to be the same thing without the limitations of a function call.

imagine a function that returns a dictionary of things that need to be changed. that's going to be some messy code to handle it. and that code could benefit from a means to insert it in each place the function that returns the dictionary is called.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#7
(Jun-22-2024, 01:21 AM)Skaperen Wrote: a function certainly should not access caller local namespace. but, in some cases, you need to work with local namespace in some common way in many places.
This is not recommended, but I have a use case of this in my scripts, when I put notes to a class of students, I use a program that defines some global variables and then calls a function that uses the variables defined in this namespace. My solution is to pass the whole namespace to the function, so the script looks like this
SPAM = 'some spammish data'
EGGS = 'some eggish data'
HAM = 'some hammish data'

from library import do_the_work
result = do_the_work(globals()) # pass the global namespace to the function
result.print_stats()
Then
def do_the_work(dic):
    print(dic['SPAM'])
    ...
This works with a globals() namespace, and do_the_work() could even modify the global namespace. I could use it also with a locals() namespace if the function only needs to read the data from this namespace, but one cannot write data in a locals() namespace.

For the global namespace, I could alternately pass the name of the current module because do_the_work() could then access the global namespace through the module
do_the_work(__name__)
then
def do_the_work(name):
    import sys
    module = sys.modules[name]
    print(module.SPAM)
    module.EGGS = 'some new value'
The idea of using global variables like this came from the documentation of a very old and famous module, the PEAK module by Philip J Eby. He speaks about « executable configuration files » and it is the kind of concept I need to put notes to my students. In only need to set a few constants and then call an engine that processes that data.
« We can solve any problem by introducing an extra level of indirection »
Reply
#8
i have the understanding that a function can access the globals() namespace on its own. of course, if the function is defined to have it passed, the caller could fake it by creating a dictionary (maybe populating it) and passing that, instead of globals().

the kind of use cases i was considering is where the main code is doing a variety of different variable settings, then for each place doing the same exact calculations that need to work with local variables (including setting some). many time capture a block of code (^u4^k^y in emacs, to capture 4 lines) and drop it (^y in emacs, in each place) in a few other places. those 4 lines modify 4 local variables. i do not want a function to be trying to pass a tuple or dict back. i prefer to keep it all simple. i might like to have a "deflocal" feature that defines a function that shares the locals() namespace with the code that defines it and calls it.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#9
(Jun-23-2024, 01:54 AM)Skaperen Wrote: many time capture a block of code (^u4^k^y in emacs, to capture 4 lines) and drop it (^y in emacs, in each place) in a few other places. those 4 lines modify 4 local variables.
exec() looks like the way to go. Just put the 4 lines in a Python string and exec() that string.
« We can solve any problem by introducing an extra level of indirection »
Reply
#10
Hey, interesting question! Generally, the result should be the same whether you insert code directly or import it, as long as both files are in the same directory and the code is unchanged. However, differences can arise if there are issues like circular imports or if the imported module has side effects that behave differently when run directly. Also, love the language joke at the end, made me chuckle!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  visual studio code python how to get source code of import module definitian umen 2 4,182 Jun-13-2020, 06:20 PM
Last Post: umen

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020