首页 > 解决方案 > __getattr__ 与文件夹中的文件夹中的 __import__ 不起作用

问题描述

我不知道发生了什么变化,但以下代码以前在我的项目中工作,现在不是:

# From Imports
from loguru import logger
from mm import colorize
from sys import exit
from typing import Callable, Any

ls: Callable[..., Any] = logger.success
li: Callable[..., Any] = logger.info
le: Callable[..., Any] = logger.error


# Results in a recursive import if in "mm", as the type_classes files import "mm" as well
def run_backup_type_functions(
    d, func, use_base, *args, **kwargs
) -> None:
    try:
        #############################################
        backup_type_folder: type = getattr(
            __import__("type_classes"), d.backup_type
        )
        #############################################
        backup_type_file: type = getattr(
            backup_type_folder, d.backup_type
        )
        argument_class: type = getattr(
            backup_type_file,
            "base" if use_base else d.argument,
            None,
        )(d, *args, **kwargs)
        getattr(argument_class, func)()
    except TypeError:
        if use_base:
            le(colorize("red", "Sorry; no base exists!"))
        else:
            le(
                colorize("red", 'Sorry; no argument "')
                + colorize("pink", a)
                + colorize("red", '"!')
            )
        exit(1)
    except Exception as e:
        le(
            colorize(
                "red",
                "Sorry; something happened! This was the error:\n\n",
            )
            + colorize("pink", e)
            + "\n"
        )
        exit(1)


def get_backup_type_attr(d, attr, use_base) -> Any:
    try:
        backup_type_folder: type = getattr(
            __import__("type_classes"), d.backup_type
        )
        backup_type_file: type = getattr(
            backup_type_folder, d.backup_type
        )
        argument_class: type = getattr(
            backup_type_file,
            "base" if use_base else d.argument,
            None,
        )(d)
        getattr(argument_class, func)()
    except TypeError:
        if use_base:
            le(colorize("red", "Sorry; no base exists!"))
        else:
            le(
                colorize("red", 'Sorry; no argument "')
                + colorize("pink", a)
                + colorize("red", '"!')
            )
        exit(1)
    except Exception as e:
        le(
            colorize(
                "red",
                "Sorry; something happened! This was the error:\n\n",
            )
            + colorize("pink", e)
            + "\n"
        )
        exit(1)

具体来说,错误在于AttributeError: module 'type_classes' has no attribute 'borg'将子文件夹作为模块从父目录文件run_backup_type_function动态导入时,变量保存要导入的子文件夹;这显示在代码的散列区域中。我的源目录树如下所示:type_classesmm2.pyd.backup_type

.
├── create.py
├── docker_cmd.py
├── __init__.py
├── LICENSE
├── meltan.py
├── mm2.py
├── mm.py
├── pull.py
├── pyproject.toml
├── README.md
├── regular_cmd.py
├── start.sh
├── test2.py
├── test2.sh
├── test.py
├── tests
├── test.sh
├── tmp
├── total_cmd.py
└── type_classes
    ├── borg
    │   ├── borg.py
    │   ├── Dockerfile
    │   ├── __init__.py
    │   └── __pycache__
    │       └── borg.cpython-37.pyc
    ├── git
    │   └── git.py
    ├── __init__.py
    ├── mercurial
    │   └── hg.py
    └── __pycache__
        ├── borg.pypy3-71.pyc
        ├── __init__.cpython-37.pyc
        ├── __init__.cpython-38.pyc
        └── __init__.pypy3-71.pyc


5 directories, 10 files

文件中没有任何内容type_classes/__init__.py。我也尝试过放入from borg import borg文件type_classes/__init__.py,但文件夹没有注册,我认为这也是原始问题发生的情况;另外,我尝试将文件从内部移动borg到其父目录,即 ie type_classes,但它给出了相同的AttributeError. 任何帮助将不胜感激!

标签: pythonpython-3.x

解决方案


回答我自己的问题,我切换到将模块路径附加到 python 路径,并从那里导入子模块:

sys_path.append(
    fullpath(
        os_path.dirname(__file__),
        "type_classes",
        d.backup_type,
    )
)
argument_class: type = getattr(
    __import__(f"mm_{d.backup_type}"),
    "base" if use_base else d.argument,
    None,
)(d, *args, **kwargs)
getattr(argument_class, func)()

推荐阅读