Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/codeigniter/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何避免循环导入_Python_Python Import - Fatal编程技术网

Python 如何避免循环导入

Python 如何避免循环导入,python,python-import,Python,Python Import,我是Python新手,之前我一直在使用像Swift这样的语言,导入不是什么大问题:您只是定义一个新类,可以从程序的另一部分访问它 我不能在Python中使用这种方式,因为这里的导入是以另一种方式工作的:不能进行循环导入,两个文件相互导入。我知道我面临这个问题是因为我用错了语言,但我不知道如何避免它 我的意思是,在大多数情况下,您可以通过将两个类合并到一个文件中来解决这个问题,但感觉不太对。此外,我还找到了类似“将导入语句移到文件末尾”的建议,但这也不是一个好主意 如果你愿意的话,我想了解Pyth

我是Python新手,之前我一直在使用像Swift这样的语言,导入不是什么大问题:您只是定义一个新类,可以从程序的另一部分访问它

我不能在Python中使用这种方式,因为这里的导入是以另一种方式工作的:不能进行循环导入,两个文件相互导入。我知道我面临这个问题是因为我用错了语言,但我不知道如何避免它

我的意思是,在大多数情况下,您可以通过将两个类合并到一个文件中来解决这个问题,但感觉不太对。此外,我还找到了类似“将导入语句移到文件末尾”的建议,但这也不是一个好主意

如果你愿意的话,我想了解Python的哲学。当我决定在一个单独的文件中创建一个类时,我应该如何组织我的项目以及我应该遵循什么

我不能在Python中使用这种方式,因为这里的导入是以另一种方式工作的:不能进行循环导入,两个文件相互导入

是的,你可以

假设我们在同一工作目录中有两个文件:

#file1.py
import file2
x = 22
y = 'spam'
print(x)
print(y)

注意当我们导入file1.py时会发生什么


file1.py导入file2.py,file2.py导入file1.py。

发生此问题的原因是,您编写Python程序就像编写Swift或Java程序一样。这种方法永远不会奏效:每种语言都是不同的,并且有不同的最佳实践。如果你写的是非Python语言的代码,那么它不仅对其他Python开发人员来说难看且无法理解,而且你正在与这种语言斗争,而不是享受它


就像python开发人员构造代码一样构造代码。将相关类分组到一个模块中。如果有一种罕见的情况,即很难避免导入周期(几乎从未发生过),则在函数或方法中导入有问题的依赖项,而不是全局范围。

您当然可以从
父项
导入
子项
,从
子项
导入
父项
。这项工作的关键是
child
不要从其模块级代码中深入探究
parent
,因为当Python在
child
中运行模块级代码时,
parent
模块只加载了一部分

以下是从
parent
导入
child
和从
child
导入
parent
时发生的情况(假设先加载了
parent
):

  • 父级模块级的代码一直运行,直到到达加载子级的语句(要么导入子级,要么从子级导入内容)。“模块级”是指不在类或函数定义中的语句。在模块级定义的类和函数也将作为模块内的对象创建。但是,函数和类方法本身还不会运行
  • 当Python在
    父级
    的模块级代码中到达
    导入子级
    语句(或等效语句)时,它将停止运行
    父级
    代码,并开始在
    子级
    中运行模块级代码。如果
    child
    通过
    import parent
    从parent import something
    导入
    parent
    ,它将获得当前部分构造状态的
    parent
    模块。因此
    child
    中的模块级代码无法访问在
    parent.py
    中的
    import child
    下面定义的对象
  • 一旦
    child
    的模块级代码完成运行,控制将返回到
    import child
    语句下面的
    parent
    ,Python将完成运行
    parent
    中的所有模块级代码
  • 如果
    child
    的模块级代码在
    import child
    语句之后试图访问在
    parent
    中定义的对象,则此过程会给您带来麻烦(因为
    parent
    仅在
    child
    加载时部分完成)。解决方案是在
    child
    的模块级导入
    parent
    ,但延迟从
    child
    访问
    parent
    中的对象,直到
    child
    parent
    完成加载。特别是,您可能需要使用
    导入父级
    ,然后从
    子级
    中的函数或方法代码访问
    父级
    ,而不是在
    子级
    的模块级代码中使用
    从父级导入某物
    。这样做是安全的,因为这些函数和方法只有在
    子模块
    父模块
    完成运行后才会运行,此时父模块的所有元素都已正确定义

    下面是一个我的意思的例子,使用您在评论中描述的设置。如果您提供更多关于代码的信息,这些代码会给您带来问题,我可以对其进行更紧密的裁剪

    第1版(不起作用)

    __主要项目:

    from user import User
    u = User()
    
    from user import User
    u = User()
    
    user.py:

    from data_manager import DataManager
    ...
    class User:
        def __init__(self, data_manager=None):
            if data_manager is None:
                data_manager = DataManager(user=self)
            self.data_manager = data_manager
    
    import data_manager as dm
    ...
    class User:
        def __init__(self, data_manager=None):
            if data_manager is None:
                data_manager = dm.DataManager(user=self)
            self.data_manager = data_manager
    
    data_manager.py:

    # next line will fail because user.py has been partly loaded
    # and user.User doesn't exist yet
    from user import User
    ...
    class DataManager:
        def __init__(self, user=None):
            ...
            if user is None:
                user = User(data_manager=self)
            self.user = user
    
    import user as user_module
    ...
    # this defines a class which will eventually create an instance
    # of user.User, but it won't try to do that until control returns
    # to __main__.py, by which point the `user` and `data_manager`
    # modules are fully defined
    class DataManager:
        def __init__(self, user=None):
            ...
            if user is None:
                user = user_module.User(data_manager=self)
            self.user = user
    
    第2版(将起作用)

    __主要项目:

    from user import User
    u = User()
    
    from user import User
    u = User()
    
    user.py:

    from data_manager import DataManager
    ...
    class User:
        def __init__(self, data_manager=None):
            if data_manager is None:
                data_manager = DataManager(user=self)
            self.data_manager = data_manager
    
    import data_manager as dm
    ...
    class User:
        def __init__(self, data_manager=None):
            if data_manager is None:
                data_manager = dm.DataManager(user=self)
            self.data_manager = data_manager
    
    data_manager.py:

    # next line will fail because user.py has been partly loaded
    # and user.User doesn't exist yet
    from user import User
    ...
    class DataManager:
        def __init__(self, user=None):
            ...
            if user is None:
                user = User(data_manager=self)
            self.user = user
    
    import user as user_module
    ...
    # this defines a class which will eventually create an instance
    # of user.User, but it won't try to do that until control returns
    # to __main__.py, by which point the `user` and `data_manager`
    # modules are fully defined
    class DataManager:
        def __init__(self, user=None):
            ...
            if user is None:
                user = user_module.User(data_manager=self)
            self.user = user
    
    请注意,在类的
    \uuuu init\uuu
    方法中的引用在类实际实例化之前不会得到解析。i、 例如,
    user=user\u module.user(data\u manager=self)
    行执行如下操作:“在当前模块中查找名为
    user\u module
    的对象;在该对象中查找
    user
    属性;构造该类的对象”。重要的是,
    data\u manager
    可以在早期安全地导入
    user
    模块(该模块已经存在,即使它只是部分构造的),但是在实例化
    DataManager
    对象之前,上面的代码实际上不会在
    user
    模块内查找任何内容,此时
    u