Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I detect if a class / variable was imported in Python 3?

This is the contents of script_one.py:

x = "Hello World"

This is the contents of script_two.py:

from script_one import x
print(x)

Now, if I ran script_two.py the output would be:

>>> Hello World

What I need is a way to detect if x was imported.
This is what I imagine the source code of script_one.py would look like:

x = "Hello World"
if x.has_been_imported:
  print("You've just imported \"x\"!")

Then if I ran script_two.py the output "should" be:

>>> Hello World
>>> You've just imported "x"!

What is this called, does this feature exist in Python 3 and how do you use it?


1 Answers

You can't. Effort expended on trying to detect this are a waste of time, I'm afraid.

Python imports consist of the following steps:

  • Check if the module is already loaded by looking at sys.modules.
    • If the module hasn't been loaded yet, load it. This creates a new module object that is added to sys.modules, containing all objects resulting from executing the top-level code.
  • Bind names in the importing namespace. How names are bound depends on the exact import variant chosen.
    • import module binds the name module to the sys.modules[module] object
    • import module as othername binds the name othername to the sys.modules[module] object
    • from module import attribute binds the name attribute to the sys.modules[module].attribute object
    • from module import attribute as othername binds the name othername to the sys.modules[module].attribute object

In this context it is important to realise that Python names are just references; all Python objects (including modules) live on a heap and stand or fall with the number of references to them. See this great article by Ned Batchelder on Python names if you need a primer on how this works.

Your question then can be interpreted in two ways:

  • You want to know the module has been imported. The moment code in the module is executed (like x = "Hello World"), it has been imported. All of it. Python doesn't load just x here, it's all or nothing.
  • You want to know if other code is using a specific name. You'd have to track what other references exist to the object. This is a mammoth task involving recursively checking the gc.get_referrers() object chain to see what other Python objects might now refer to x.

The latter goal is made the harder all the further in any of the following scenarios:

  • import script_one, then use script_one.x; references like these could be too short-lived for you to detect.
  • from script_one import x, then del x. Unless something else still references the same string object within the imported namespace, that reference is now gone and can't be detected anymore.
  • import sys; sys.modules['script_one'].x is a legitimate way of referencing the same string object, but does this count as an import?
  • import script_one, then list(vars(script_one).values()) would create a list of all objects defined in the module, but these references are indices in a list, not named. Does this count as an import?
like image 71
Martijn Pieters Avatar answered May 10 '26 13:05

Martijn Pieters



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!