4

Essentially, I'm wondering if it's possible to do something like from .my_script import None in my package's __init__.py to execute my_script.py without introducing undesired variables into the namespace. I know you can do from . import my_script; del my_script - I thought it was possible there was a shortcut for this.

QuaternionsRock
  • 832
  • 7
  • 14
  • No shortcut, because it's not a common use-case for importing a module. – chepner Aug 04 '21 at 14:57
  • Would kind of be nice. Scapy makes extensive use of this. You need to import a module for the packet types to be "registered" so they're automatically parsed. But ya, this isn't very common, so it's not surprising that there isn't a shortcut. – Carcigenicate Aug 04 '21 at 14:59
  • If the module is designed to be used like this, it could delete all the names it defines at the end. – Barmar Aug 04 '21 at 15:36

1 Answers1

0

Consider Local import statements.

You could do the import foo inside a function, which means it will not clutter the global namespace. However, there is an option that does not require a function def:

import foo is roughly equivalent to this statement:

foo = __import__('foo', globals(), locals(), [], -1)

That is, it creates a variable in the current scope with the same name as the requested module, and assigns it the result of calling __import__() with that module name and a boatload of default arguments.

However, specifying that -1 there seems to no longer be supported in python3. According to the docs, the level indicates

0 means only perform absolute imports. Positive values for level indicate the number of parent directories to search relative to the directory of the module calling __import__().

So we will have to go with 0... or if it needs to search in a parent directory, a corresponding positive number.


As an example, I have two files in the same folder.

foo.py

print("Foo loaded")

bar.py

print("Hello")
__import__('foo', globals(), locals(), [], 0)
print("World")

output

> python bar.py
Hello
Foo loaded
World

If you want this to be a shortcut because you do this often, you could define your own, easier to use, function that takes the module name and internally just does this.

lucidbrot
  • 5,378
  • 3
  • 39
  • 68