试图理解 __init__.py 结合 getattr

Trying to understand __init__.py combined with getattr

我正在尝试理解一段 Python 代码。

首先,我有以下文件结构:

folder1--
   model
     __init__.py
     file1.py
     file2.py
  __init__.py

文件夹folder1中的__init__.py没有任何内容。 文件夹模型中的__init__.py有以下内容:

import os
files = os.listdir(os.path.split(os.path.realpath(__file__))[0])
files.remove('__init__.py')
for file in files:
    if file.endswith('.py'):
        exec('from .{} import *'.format(file[:-3]))

话虽如此,我在 python 中有一些代码使用了以上所有内容 现在,我试图理解以下代码

from folder1 import model as mymodel

我的第一个问题是这是做什么的?我的意思是模型是一个文件夹名称对吗?它不是一个对象。是吗? mymodel 这里究竟导入了什么?

然后在相同的代码中它说

global args, cfg, is_fov120
args = parser.parse_args()
model = getattr(mymodel, args.arch)(sync_bn=False)

显然有一些参数叫做 arch。这里发生了什么,之后 model 有什么?

编辑

当我做 print(mymodel)

我明白了 <module 'folder1.model' from 'C:\path\to\folder1\model\__init__.py'>

进一步调查,我发现我已经从文件夹模型中的文件中导入了所有对象。

mymodel.files 给出文件夹中的文件列表,如果在 file1.py 或 file2.py 中定义了某些变量,我可以调用 mymodel.somevariable。至于 classes 我必须先创建一个对象 x=mymodel.aClass() 然后我可以访问对象的元素 x.someElement.

最后我发现 getattr 正在从模型内部的文件中获取 class,我可以猜测 sync_bn=False 是 [=60] 的构造函数的参数=].

所以最后,model 是 class 的一个对象。

如果您希望将文件夹作为 python 模块,该文件夹必须包含 __init__.py,即使它是空的。然后就可以导入剩下的了。

import os
files = os.listdir(os.path.split(os.path.realpath(__file__))[0]) #get the folder's content
files.remove('__init__.py')                                      #remove __init__.py since it is empty
for file in files:                                               #loop through the files
    if file.endswith('.py'):                                     #if it is a python file
        exec('from .{} import *'.format(file[:-3]))              #import

上面的代码,导入每隔 .py 个文件而不是 __init__,它是空的。


from folder1 import model as mymodel

这里 folder1 是模块,model 是您从(文件夹)导入的对象 model 在这种情况下,因为它现在被导入到 folder1 的 __init__.py,现在它是 folder1 的一部分(这是一个讨论过的模块)。


model = getattr(mymodel, args.arch)(sync_bn=False)

此行等于:mymodel.attr,其中 attr 是对象的所需属性。你能 post 关于 getattr 的更多代码吗,因为我不知道 args.arch 指的是什么。

正如 Pyzard 所建议的,getattr 方法获取一个属性,这是一个函数,因为它正在被调用,而方法是该函数返回的值。在这种情况下 sync_bn 是无关紧要的,但了解更多 args.arch 仍然会有帮助。


有关 getattr function, how import works. Better explanation of how init.py works 的更多信息。