最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

python - How to use relative import in Manim? - Stack Overflow

programmeradmin2浏览0评论

I am working with a set of Manim projects and my project directory tree looks like this:

  • (dir) ManimProjects (root directory)
    • (dir) public (contains libraries shared by all projects)
      • (file) public_mobjects.py
    • (dir) Project1
      • (file) scene.py
    • (dir) Project2
      • (file) scene.py

So, for example, in Project1's scene.py, I would like to import the public_mobjects model, what should I do?

I have tried using from ..public.public_mobjects import ..., which is the standard relative import syntax in Python. but this results in an error:

Manim Community v0.19.0

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "<user-dir>\AppData\Local\Programs\Python\Python313\Scripts\manim.exe\__main__.py", line 7, in <module>
    sys.exit(main())
             ~~~~^^
  File "<user-dir>\AppData\Local\Programs\Python\Python313\Lib\site-packages\click\core.py", line 1161, in __call__
    return self.main(*args, **kwargs)
           ~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "<user-dir>\AppData\Local\Programs\Python\Python313\Lib\site-packages\click\core.py", line 1082, in main
    rv = self.invoke(ctx)
  File "<user-dir>\AppData\Local\Programs\Python\Python313\Lib\site-packages\click\core.py", line 1697, in invoke
    return _process_result(sub_ctxmand.invoke(sub_ctx))
                           ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
  File "<user-dir>\AppData\Local\Programs\Python\Python313\Lib\site-packages\click\core.py", line 1443, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<user-dir>\AppData\Local\Programs\Python\Python313\Lib\site-packages\click\core.py", line 788, in invoke
    return __callback(*args, **kwargs)
  File "<user-dir>\AppData\Local\Programs\Python\Python313\Lib\site-packages\manim\cli\render\commands.py", line 121, in render
    for SceneClass in scene_classes_from_file(file):
                      ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "<user-dir>\AppData\Local\Programs\Python\Python313\Lib\site-packages\manim\utils\module_ops.py", line 167, in scene_classes_from_file
    module = get_module(file_path)
  File "<user-dir>\AppData\Local\Programs\Python\Python313\Lib\site-packages\manim\utils\module_ops.py", line 67, in get_module
    spec.loader.exec_module(module)
    ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^
  File "<frozen importlib._bootstrap_external>", line 1026, in exec_module
  File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
  File "<outer-dir-of-manim-projects>\ManimProjects\CircleOfFifth\scene.manim.py", line 40, in <module>
    from ..public.text_config import *
ModuleNotFoundError: No module named 'd:\\'

I know that when direcly running a python code file, when relative import is used I will need py -m ... to resolve relative imports, but manim doesnot run a python file directly. So what is the correct method of doing that in Manim?

Currently I program with Manim in VSCode with the "Manim Sideview" plugin. My Python version is 3.13.1 and Manim version 0.19.0.

I am working with a set of Manim projects and my project directory tree looks like this:

  • (dir) ManimProjects (root directory)
    • (dir) public (contains libraries shared by all projects)
      • (file) public_mobjects.py
    • (dir) Project1
      • (file) scene.py
    • (dir) Project2
      • (file) scene.py

So, for example, in Project1's scene.py, I would like to import the public_mobjects model, what should I do?

I have tried using from ..public.public_mobjects import ..., which is the standard relative import syntax in Python. but this results in an error:

Manim Community v0.19.0

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "<user-dir>\AppData\Local\Programs\Python\Python313\Scripts\manim.exe\__main__.py", line 7, in <module>
    sys.exit(main())
             ~~~~^^
  File "<user-dir>\AppData\Local\Programs\Python\Python313\Lib\site-packages\click\core.py", line 1161, in __call__
    return self.main(*args, **kwargs)
           ~~~~~~~~~^^^^^^^^^^^^^^^^^
  File "<user-dir>\AppData\Local\Programs\Python\Python313\Lib\site-packages\click\core.py", line 1082, in main
    rv = self.invoke(ctx)
  File "<user-dir>\AppData\Local\Programs\Python\Python313\Lib\site-packages\click\core.py", line 1697, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
  File "<user-dir>\AppData\Local\Programs\Python\Python313\Lib\site-packages\click\core.py", line 1443, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<user-dir>\AppData\Local\Programs\Python\Python313\Lib\site-packages\click\core.py", line 788, in invoke
    return __callback(*args, **kwargs)
  File "<user-dir>\AppData\Local\Programs\Python\Python313\Lib\site-packages\manim\cli\render\commands.py", line 121, in render
    for SceneClass in scene_classes_from_file(file):
                      ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "<user-dir>\AppData\Local\Programs\Python\Python313\Lib\site-packages\manim\utils\module_ops.py", line 167, in scene_classes_from_file
    module = get_module(file_path)
  File "<user-dir>\AppData\Local\Programs\Python\Python313\Lib\site-packages\manim\utils\module_ops.py", line 67, in get_module
    spec.loader.exec_module(module)
    ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^
  File "<frozen importlib._bootstrap_external>", line 1026, in exec_module
  File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
  File "<outer-dir-of-manim-projects>\ManimProjects\CircleOfFifth\scene.manim.py", line 40, in <module>
    from ..public.text_config import *
ModuleNotFoundError: No module named 'd:\\'

I know that when direcly running a python code file, when relative import is used I will need py -m ... to resolve relative imports, but manim doesnot run a python file directly. So what is the correct method of doing that in Manim?

Currently I program with Manim in VSCode with the "Manim Sideview" plugin. My Python version is 3.13.1 and Manim version 0.19.0.

Share Improve this question asked Feb 7 at 2:55 F. X. P.F. X. P. 133 bronze badges New contributor F. X. P. is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
Add a comment  | 

1 Answer 1

Reset to default 0

If you don't want to restructure your project, or edit $PYTHONPATH, or edit sys.path by hand, or edit __package__, or attempt adding __init__.py you could try solving the problem by using a tool meant to solve relative imports.


Here is one such tool $ pip install importmonkey and then you can do this:

# =============== example structure ===============
├─ src
│   └─ project
│       └─ mymodule.py
└─ test
    └─ test.py
# =============== importing in test.py ===============

from importmonkey import add_path
add_path("../src/project")  # relative to current __file__
import mymodule

# add as many paths as needed, absolute or relative
# unix path conventions work so you can use '..' and '.'
# add_path validates the paths and returns added path as string



Why the Problem Occurs

The issue happens because relative imports in Python depend on the __package__ attribute, which is typically set when running a module within a package using python -m package.module However, Manim executes scripts differently—it loads them dynamically via importlib, causing relative imports (from ..public import public_mobjects) to fail.

Additionally, sys.path (which Python uses to search for modules) does not automatically include sibling directories, meaning Project1/scene.py cannot naturally import public/public_mobjects.py.

How the Solution Works

The proposed solution avoids modifying Python’s default import system (i.e., no changes to PYTHONPATH, or package structure). It instead dynamically adds directories to Python’s import path


Disclosure: I am the author of importmonkey.

发布评论

评论列表(0)

  1. 暂无评论