I have a bot that is based on a ready-made project, and now it's time to write my own. I decided to do the same import of plugins:

# содержимое /plugins/__init__.py import importlib import pkgutil __all__ = [] def import_plugins(package): if isinstance(package, str): package = importlib.import_module(package) for loader, name, is_pkg in pkgutil.walk_packages(package.__path__): full_name = package.__name__ + '.' + name module = importlib.import_module(full_name) for name in dir(module): if name[0] == "_": continue e = module.__getattribute__(name) if e in __all__: continue if True: __all__.append(e.__name__) globals()[e.__name__] = e if is_pkg: import_plugins(full_name) import_plugins(__name__) 

So, there is no problem running from PyCharm, but if you run from the command line, you will get an error:

Traceback (most recent call last):
File "Camelia.py", line 12, in
settings = Settings.Settings ()
File "C: \ Users \ ShadowOfLife \ PycharmProjects \ AeterrnoPy \ Settings.py", line 10, in __init__
self.inner_data = InnerDataPlugin ()
NameError: name 'InnerDataPlugin' is not defined

What am I doing wrong? Is it possible to force such an import to work from the command line?

Project structure:

/ Plugins
- / AeterrnoPy
- / Base
- / Data
-------- __init__.py
-------- InnerData.py # here is the InnerDataPlugin ()
- / ezpy
- __init__.py # here is the code to import
/ utils
Camelia.py # bot
Settings.py # here plugins are imported

And the contents of Settings:

 from Plugins import * class Settings: __slots__ = ("inner_data", "plugins", "user_plugins") def __init__(self): self.plugins = () self.user_plugins = () self.inner_data = InnerDataPlugin() self.plugins = ( AntiFloodPlugin(), self.inner_data, PairPlugin("pair test", "pt"), TestingPlugin("test", "tst"), ) self.user_plugins = ( PairUP("pair test", "pt"), ) 

UPD: I apologize for using images, corrected

  • Replace the images in question with text. - Sergey Gornostaev
  • text information is better to attach as text: a) easier to read; b) can be copied; c) the search works. You can correct the question text by clicking below to edit the question text - aleksandr barakin
  • In which file is the InnerDataPlugin defined? - Bogdan

2 answers 2

The problem is that Pycharm automatically adds all directories with project modules to PYTHONPATH. When you run the script from the console - it does not see the directories by which your modules are scattered (for many reasons). And there are two ways out:

  1. Correct - just use relative imports, for example:

    from ..Plugins import *

    import .Plugins

(Experiment with the paths to understand how it all works)

  1. Not very correct. Create in the main project directory init .py. Import all your internal modules into it. Add the project's root directory to the PYTHONPATH variable of your OS, or write directly at the very top of the main file:

    import sys

    sys.path.append ('/ path / to_my_project')

    In general, the answer Alex did not help me, nothing has changed. I have already solved the problem, but I cannot explain why and how. I imported a base plugin into __init__.py, from which the rest are inherited, and instead of adding everything to __all__, I add only BasePlugin subclasses. Now it works both from the console, and from PyCharm, and from another device too.
    That is, instead of:

     if True: __all__.append(e.__name__) globals()[e.__name__] = e 

    Now:

     if isinstance(e, type) and issubclass(e, BasePlugin) and e.__module__ == module.__name__: __all__.append(e.__name__) globals()[e.__name__] = e 

    The necessary plugins in the variable were in both cases, but for some reason, if there was something superfluous, the import did not work on the command line.