I am trying to understand a piece of Python code.
First, I have the following file structure:
folder1--
model
__init__.py
file1.py
file2.py
__init__.py
The __init__.py
in the folder folder1 has nothing.
The __init__.py
in the folder model has the following:
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]))
With that said, I have some code in python that uses all the above Now, I am trying to understand the following code
from folder1 import model as mymodel
My first question is what does this do? I mean model is a folder name right? it is not an object. or is it? What is exactly importing as mymodel
here?
then later in the same code it says
global args, cfg, is_fov120
args = parser.parse_args()
model = getattr(mymodel, args.arch)(sync_bn=False)
Apparently there is some arguments called arch
. What is happening here and what does model
have after this?
When I do print(mymodel)
I get
<module 'folder1.model' from 'C:\\path\\to\\folder1\\model\\__init__.py'>
Investigating even more I can see that I have imported all the objects from the files in the folder model.
mymodel.files
gives the list of files in the folder, and I can call mymodel.somevariable
if some variable was defined in file1.py or file2.py. As for classes I have to create an object first like x=mymodel.aClass()
and then I can access the elements of the object x.someElement
.
Finally I found out that getattr
is getting a class from the files inside model and I can guess that the sync_bn=False
is a parameter to the constructor of that class.
So in the end, model is an object of that class.
If you desire to have a folder as a python module, the folder must contain an __init__.py
, even if it is empty. Then you can import the rest.
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
The above code, imports every other .py
files than the __init__
, which is empty.
from folder1 import model as mymodel
Here folder1
is the module, and model
is the object you imported from (folder) model
in this case, since it is now imported to folder1's __init__.py
, and now it is part of folder1 (which is a module as discussed).
model = getattr(mymodel, args.arch)(sync_bn=False)
This line is equal to: mymodel.attr
, where attr
is the desired attribute of the object. Can you please post more code around the getattr
, since I can't tell what args.arch
are refering to.
As Pyzard suggested, the getattr
method gets an attribute, which is a function, since it is getting called, and method is the value that this function returned. In this case sync_bn
is irrevelant, but knowing more about args.arch
would still help.
More about the getattr function, how import works. Better explanation of how init.py works.