zoukankan      html  css  js  c++  java
  • python:关于py文件之间相互import的问题

    问题背景

    调试脚本时,遇到一个问题:ImportError: cannot import name 'A' from 'study_case.a' (/Users/rchera/PycharmProjects/test/study_case/a.py)

    具体情况是这样婶儿的:

    前些日子写了一个py文件,它的功能主要是创建数据(暂且称为create_data.py,每条数据会生成一个唯一的id);

    同时写了另一个py文件,它的功能主要是操作数据,例如对数据进行编辑、删除等(暂且称为operate_data.py);

    要对数据进行操作的话,必须传入数据对应的唯一id,所以在operate_data.py导入create_data.py生成数据的方法

    至此,一切都很顺利,还没有什么问题

    由于一些情况,我需要在生成一条数据后,紧接着要把它删除,

    开始打算直接在create_data.py中再写一个删除数据的方法,不过后来想到之前已经在operate_data.py中定义好删除数据的方法了,

    这样的话,直接在create_data.py导入operate_data.py,引用其删除数据的方法应该也行

    但是实际却并未按照预想的那样,按照上面的想法调好脚本后,create_data.py和operate_data.py都无法运行了,会提示顶部列出的错误~

    在网上搜索了一下,大致原因是:create_data.py和operate_data.py两个文件互相调用了

    当然并不是说python不能循环引用,只是我的写法有问题,然后我继续深入搜索了一番,在一些大神的博客里找到了解决方法

    参考文章:

    https://fishc.com.cn/forum.php?mod=viewthread&tid=60873&page=1#pid2337627

    https://www.zhihu.com/question/19887316

    https://blog.igevin.info/posts/how-to-avoid-python-circle-import-error/

    ps.大神都建议不要在python中交叉循环引用(即不要在a中调用b,然后b中又调用a),最好规划好代码的层级,哪些是公共方法,哪些是业务逻辑,把这些提前想好,有利于后期的维护~

    OK,接下来按照网上给出的方法,用一个例子演示下如何解决python中循环引用的问题

    实例演示

    准备2个py文件

    a.py

    from study_case.b import B
    
    
    class A:
        @staticmethod
        def a1(number):
            return number * number
    
        @staticmethod
        def a2():
            value = B().b(1)
            return value
    
    
    if __name__ == '__main__':
        t = A()
        print(t.a1(2))

    b.py

    from study_case.a import A
    
    
    class B:
        @staticmethod
        def b(x):
            value = A().a1(1)
            return value + x
    
    
    if __name__ == '__main__':
        t = B()
        print(t.b(1))

    文件结构如下

    按照上面这种写法,运行a或b,都会报错,如下

     解决方法1: 在文件的顶部引入,不要用from,使用绝对引入

    例如,修改b.py文件内容如下,直接引入a文件

    import study_case.a
    
    
    class B:
        @staticmethod
        def b(x):
            value = study_case.a.A().a1(1)   
            return value + x
    
    
    if __name__ == '__main__':
        t = B()
        print(t.b(1))

    不过我试了下,如果用from的话,只导入a文件这个层级,也不会报错,如下

    from study_case import a
    
    
    class B:
        @staticmethod
        def b(x):
            value = a.A().a1(1)
            return value + x
    
    
    if __name__ == '__main__':
        t = B()
        print(t.b(1))

    解决方法2: 函数顶部引入,可以用from

    例如,修改b.py文件内容如下,在函数名下方第一行引入a文件的类

    class B:
        @staticmethod
        def b(x):
            from study_case.a import A
            value = A().a1(1)
            return value + x
    
    
    if __name__ == '__main__':
        t = B()
        print(t.b(1))
  • 相关阅读:
    深入理解系统调用
    基于mykernel 2.0编写一个操作系统内核
    交互式多媒体图书平台的设计与实现
    Ubuntu下VSCode调试环境搭建指南-C语言篇
    码农的自我修养之必备技能 学习笔记
    工程化编程实战callback接口学习笔记
    CentOS7.4网络配置
    R-CNN
    CUDA整理
    CUDA by Example 第四章 julia集
  • 原文地址:https://www.cnblogs.com/hanmk/p/13402910.html
Copyright © 2011-2022 走看看