【问题标题】:PyCharm procedural __all__ generation and syntax highlightingPyCharm 程序 __all__ 生成和语法高亮
【发布时间】:2019-06-23 16:20:06
【问题描述】:

我正在使用这个装饰器以 DRY 方式管理 __all__

def export(obj):
    mod = sys.modules[obj.__module__]
    if hasattr(mod, '__all__'):
        mod.__all__.append(obj.__name__)
    else:
        mod.__all__ = [obj.__name__]

    return obj

对于使用import * 导入的名称,PyCharm 会发出unresolved reference 错误,这是可以理解的,因为它在分析之前不会运行代码。但这是一个明显的不便。

你会如何解决它(或者可能已经解决了)?

我的假设

  • 添加一些自动 linter 插件或更改现有 PyCharm 的检查代码都可以。
  • 实际编辑 .py 源的内容是可行的,但不是很好。
  • 此方法可能不是最好的方法,因此建议另一种处理导出的便捷技术也很好。

【问题讨论】:

  • 可以使用pyi存根,见PEP-484PEP-561
  • @user2235698 不错!您能否建议一些自动更新此存根的方法并提供 py、pyi 文件及其用法的简单示例(以了解您的想法应该如何工作)?我会勾选那个答案。
  • 我还没有看到足够好的工具来自动更新存根,您可以从stubgen 开始并手动更新存根以使其更精确。 typeshedattrs 可能是一个很好的例子,大多数 linter 都支持这样的存根。

标签: python pycharm static-analysis


【解决方案1】:

您可能对管理__all__ 的替代方法感兴趣:

https://pypi.org/project/auto-all/

这提供了一个start_all()end_all() 函数来放置在您的模块中您想要使其可访问的项目周围。这种方法适用于 PyCharms 代码检查。

from auto_all import start_all, end_all

# Imports outside the start and end function calls are not included in __all__.
from pathlib import Path

def a_private_function():
    print("This is a private function.")

# Start defining externally accessible objects.
start_all(globals())

def a_public_function():
    print("This is a public function.")

# Stop defining externally accessible objects.
end_all(globals())

我觉得这是管理__all__ 的一种合理方法,并且我在更复杂的包上使用过这种方法。该包的源代码很小,因此可以很容易地直接包含在您的代码中,以避免在需要时避免外部依赖。

我使用它的原因是我有一些模块需要“导出”很多项目,并且我想将导入的项目排除在导出列表之外。我有多个开发人员在处理代码,很容易添加新项目而忘记将它们包含在 __all__ 中,因此自动化这会有所帮助。

【讨论】:

  • 好吧,仍然不太适合 linter,但我想该项目最终会实现这一点。目前是最接近完美的解决方案,感谢分享!
猜你喜欢
  • 1970-01-01
  • 2012-11-02
  • 2012-02-11
  • 2014-05-15
  • 1970-01-01
  • 2016-08-16
相关资源
最近更新 更多