代码之家  ›  专栏  ›  技术社区  ›  Erik Cederstrand

当用户导入不推荐使用的变量时引发自定义导入错误[重复]

  •  1
  • Erik Cederstrand  · 技术社区  · 6 年前

    我写了一个包,其中一个子模块包含一个模块级变量 deprecated_var 我想删除,因为这是一个可怕的错误。

    mypkg
      - mymodule
        - __init__.py
    

    ImportError ,我想打印一条消息,说明它们的导入已被弃用,以及它们应该做什么。所以不是:

    >>> from mypkg.mymodule import deprecated_var
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ImportError: cannot import name 'deprecated_var'
    

    我想让用户看到这样的东西:

    >>> from mypkg.mymodule import deprecated_var
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ImportError: mypkg.mymodule.deprecated_var was removed. Replace 
      with "from foo.bar import Baz; deprecated_var = Baz()"
    

    2 回复  |  直到 6 年前
        1
  •  2
  •   FHTMitchell    6 年前

    我认为这在Python3.7之前是不可能的。

    然而,在Python3.7或更高版本中,这可以通过使用模块级来实现 __getattr__ 加入 PEP562 .

    你可以用like so:

    #_deprecated_vars is a dict of keys -> alternatives (or None)
    _deprecated_vars: Dict[str, Optional[str]] = {
            'deprecated_var': 'from foo.bar import Baz; deprecated_var = Baz()', 
            'other_deprecated_var': None
        }
    
    def __getattr__(name):
        if name in _deprecated_vars:
            alt_text = '{name} was removed from module {__name__}'
            replace_text = _deprecated_vars[name]
            if replace_text is not None:
               alt_text += f'. Replace with {replace_text!r}.'
            raise AttributeError(alt_text)
        raise AttributeError(f"module {__name__} has no attribute {name}")
    

    from a.b import deprecated_var . 这是为了 import a.b; a.b.deprecated_var

        2
  •  2
  •   9769953    6 年前

    对于您的特定示例,可以使用以下命令:

    mymodule/__init__.py

    #deprecated_var = 5
    replacement_var = 6
    

    mymodule/deprecated_var.py :

    raise ImportError("deprecated_var is deprecated. Use mypkg.mymodule.replacement_var instead")
    

    当这引起习俗 ImportError 直接导入变量时:

    >>> from mymodule import deprecated_var
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File ".../mymodule/deprecated_var.py", line 1, in <module>
        raise ImportError("deprecated_var is deprecated. Use mypkg.mymodule.replacement_var instead")
    ImportError: deprecated_var is deprecated. Use mypkg.mymodule.replacement_var instead
    

    AttributeError 而不是弃用警告:

    >>> import mymodule
    >>> mymodule.deprecated_var
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: module 'mymodule' has no attribute 'deprecated_var'