【问题标题】:How make PyCharm automatically suggest function of a class modified by metaclass?如何让 PyC​​harm 自动提示元类修改的类的功能?
【发布时间】:2020-09-30 02:18:57
【问题描述】:

为了简化处理数据库表的代码,我写了一个元类工厂,如下所示:

    #metaClass factory
    def base_service(clz_of_model):

      @db.transactional
      def add(self, obj):
        m = clz_of_model(**obj)
        db.session.add(m)
        return m

      class BaseService(type):
         def __new__(mcs, name, base, attrs):
            attrs["add"] = add
            return super().__new__(mcs, name, base, attrs)

      return BaseService

    #define a model
    class UserModel(Base):
       #....

    #define a service
    class UserService(object,metaclass=base_service(UserModel):
       #....

    #using service
    user_service=UserSerivce()
    user_service.add({"name":'tom'})

代码确实有效,但一个不便之处是:

当我输入“user_servce”时。在 Pycharm 中,IDE 不会建议 user_service 具有由元类定义的“添加”功能。

PyCharm 的建议如何发挥作用?我能有更好的解决方案来使用 Python 的元类吗?

【问题讨论】:

    标签: pycharm metaclass


    【解决方案1】:

    你不能。

    由于这不是静态可检测到的简单原因 - 不是 this,也不是其他数十种向类添加动态方法和属性的方法。

    如果 pycharm 依赖于静态分析 Python 代码来建议自动完成,它永远无法超越最简单、明确的代码。

    你的类只有在新方法被创建为一个活的 Python 对象后才能看到它。

    我认为有一些工具可以使用这种方法(尽管在运行导入的模块时会触发副作用)——当然,如果你使用 Jupyter 笔记本进行编码,在你的类声明下面的单元格中,添加方法将是可见的。

    我知道最近有一种 IDE 使用嵌入式笔记本的趋势,而不仅仅是编辑文件 - 也许有一个工作流程允许您使用“活”对象进行开发,并将所有单元格内容保存到单个 .完成后创建py文件。

    或者,如果您的类与您正在编辑的类位于一个单独的 Python 项目中,那么 pycharm 本身将导入模块并能够自省当前的类。

    但最重要的是,仍然存在一个事实:不应该依赖 IDE 和其他工具辅助来编写他们需要的代码。如果辅助工具可用并且有效,那么一切都很好,否则,只需编写代码。

    如果这听起来很生硬,我很抱歉。但是如果没有实际运行动态修改代码,您想要的只是不可能的。

    如果 pycharm 甚至无法对其他项目中的文件执行此操作,并且您希望在 他们 编辑此项目时使用动态方法向您的项目的 3rdy 方用户显示,解决方法将是让您的元类使用添加的方法生成 Python 文件 - 并将这些修改的部分作为您的项目实际使用的部分。您将添加一个“构建”步骤来读取一个目录中的“模板”类,然后在项目安装时渲染到另一个目录中的“完整”类。这样,即使是仅依赖于代码静态分析的工具也能找到它。但是我认为如果动态代码不在当前正在编辑的文件/项目中,pycharm和其他工具可以进行实时自省。

    【讨论】:

    • pycharm 没有理由必须使用静态分析,这可能是一个标志:使用导入而不是静态分析进行输入
    猜你喜欢
    • 2012-08-27
    • 2021-01-29
    • 2015-12-16
    • 2011-07-15
    • 2018-11-09
    • 2013-09-26
    • 1970-01-01
    • 2016-11-09
    • 2020-01-27
    相关资源
    最近更新 更多