PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Thursday, August 25, 2022

[FIXED] How to call a dynamically loaded module without raising NameError: name 'name' is not defined

 August 25, 2022     dynamic, module, python     No comments   

Issue

I'm trying to create a 'plugin' system, where placing a python file (or package) inside a 'plugins' folder, and reloadings the script will dynamically call the functions inside those files.

I have the following file structure

main.py
plugins -
         |- test.py
         |- status.py

I import the test.py/status.py modules like so:

sys.path.append('plugins')

plugins_list = os.listdir('plugins')
plugins_list.remove('__pycache__') # prevenet error from being raised

for module in plugins_list:
    importlib.import_module('plugins.'+module[:-3])
    print("Imported {}".format('plugins.'+module[:-3]))

Script runs fine. I try print(sys.modules.keys()) and plugins.test and plugins.status have indeed been imported. However now when I attempt to call any functions inside, a name error is raised NameError: name 'plugins' is not defined

This takes me to Python custom module name not defined where they explain that plugins.status.get_status() will not work. I somehow have to import it differently. The issue is that I've used importlib so I'm not sure how to achieve that.

I've looked at the documentation page:

importlib.import_module(name, package=None)

Import a module. The name argument specifies what module to import in absolute or relative terms (e.g. either pkg.mod or ..mod). If the name is specified in relative terms, then the package argument must be set to the name of the package which is to act as the anchor for resolving the package name (e.g. import_module('..mod', 'pkg.subpkg') will import pkg.mod).

The import_module() function acts as a simplifying wrapper around importlib.__import__(). This means all semantics of the function are derived from importlib.__import__(). The most important difference between these two functions is that import_module() returns the specified package or module (e.g. pkg.mod), while __import__() returns the top-level package or module (e.g. pkg).

It seems as if __import__() would solve my problem, however it recommends I do not use that.

Additionally I feel like defining something as the second importlib arguement may sort the problem, however I'm not sure what

How do I make it so that the functions could be run?


Solution

When you are running importlib.import_module('plugins.'+module[:-3]) the value that is getting returned is the imported module. It's not being assigned to anything so it's getting cleaned up almost as soon as it's imported. You can dynamically add to the namespace, but it's not recommended.

Try something like this, where you're assigning the imported module to a dictionary, that you can then reference the module via the dictionary based on the module name:

plugin_dict = {}

for module in plugins_list:
    modname = module[:-3]
    plugin_dict[modname] = importlib.import_module('plugins.'+modname)
    print("Imported {}".format('plugins.'+module[:-3]))
    
    
    
plugin_dict['status'].get_status()


Answered By - user12842282
Answer Checked By - Willingham (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing