python __init__.py的一些用法
刚开始接触robosuite,在看demo的时候发现自己不懂__init__.py的问题。于是网上搜了些资料,试验了下,得出如下结果:
(1).py文件称为模块,含init的目录称为包。
(2)存在相对导入语句的模块是不能直接运行的,被调用时没问题。
(3)在调用、导入一个包时会执行其__init__.py下的代码,所以__init__.py一般用来初始化。本文试验创建如下目录,
sitep/__init__.py:
import numpy as np
print('init')
test11.py:
import sitep
print(dir())
print(dir(sitep))
dir() 函数不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。
执行test11.py:
init
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'sitep']
['__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'np']
(4)在sitep的init中导入的模块或包将作为包的方法,可通过dir(包名)查看,在主程序中要使用时有两种方式:一是from sitep import *,二是在调用时使用sitep.api
4.1
test11.py:
from sitep import *
print(dir())
a=np.array(1)
print(a)
执行test11.py:
init
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'np']
1
可以看到在dir的变量中包含了np,此时可以直接调用。
4.2
test11.py:
import sitep
print(dir())
a=sitep.np.array(1)
print(a)
执行test11.py:
init
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'sitep']
1
(5)主程序在使用 from sitep import *时,如果sitep的init里设置了all参数则在主程序会导入all参数中的模块或包,不会导入元素的子目录,导入操作会继续查找 subpackage_1 和 subpackage_2 中的 init.py 并执行,此时不会导入init中导入的模块或包,若init中未设置all参数则会导入init中导入的模块或包。
在sitep/init.py添加一行:
__all__=['sitep1','sitep2']
此时sitep/init.py:
import numpy as np
print('init')
__all__=['sitep1','sitep2']
sitep1/__init__.py:
import sys
print('sitep,init')
test11.py:
from sitep import *
print(dir())
执行test11.py:
init
sitep,init
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'sitep1', 'sitep2']
可以看到dir变化能量中没有了np,添加了sitep1和sitep2,无test等。同时执行了sitep1/__init__.py中的代码。
(6)导入模块时,如from a.b.c import d ,若abc都为包则会按顺序执行相应的__init__.py,若在执行a的init时遇到from e.f.g import t,又会先顺序执行的e,f,g的__init__.py,依次类推。