python module加载
init.py的作用
ros2 加载过程
ros2pkg 文件目录
|-- CHANGELOG.rst
|-- package.xml
|-- resource
| `-- ros2pkg
|-- ros2pkg
| |-- __init__.py
| |-- api
| | |-- __init__.py
| | `-- create.py
| |-- command
| | |-- __init__.py //说明这是一个包
| | `-- pkg.py
| |-- resource
| | |-- __init__.py
| | |-- ament_cmake
| | |-- ament_python
| | |-- cmake
| | |-- cpp
| | `-- package_environment
| `-- verb
| |-- __init__.py
| |-- create.py
| |-- executables.py
| |-- list.py
| |-- prefix.py
| `-- xml.py
|-- setup.py
`-- test
|-- test_api.py
|-- test_cli.py
|-- test_copyright.py
|-- test_flake8.py
|-- test_pep257.py
`-- test_xmllint.py
当我们运行ros2 pkg list
时,会调用到rospkg包中,进入点,就是entry_points.txt中定义的
[ros2cli.command]
pkg = ros2pkg.command.pkg:PkgCommand
[ros2cli.extension_point]
ros2pkg.verb = ros2pkg.verb:VerbExtension
[ros2pkg.verb]
create = ros2pkg.verb.create:CreateVerb
executables = ros2pkg.verb.executables:ExecutablesVerb
list = ros2pkg.verb.list:ListVerb
prefix = ros2pkg.verb.prefix:PrefixVerb
xml = ros2pkg.verb.xml:XmlVerb
当运行ros2 pkg list
,首先是进入这个函数
from ros2cli.command import add_subparsers_on_demand #导入方法用于命令解决
from ros2cli.command import CommandExtension #导入类
class PkgCommand(CommandExtension):
"""Various package related sub-commands."""
def add_arguments(self, parser, cli_name):
self._subparser = parser
# add arguments and sub-commands of verbs
add_subparsers_on_demand(
parser, cli_name, '_verb', 'ros2pkg.verb', required=False)
def main(self, *, parser, args):
if not hasattr(args, '_verb'): #hasattr() 函数用于判断对象是否包含对应的属性。
# in case no verb was passed
self._subparser.print_help()
return 0
extension = getattr(args, '_verb') #函数用于返回一个对象属性值。
# call the verb's main method
return extension.main(args=args)
‘list = ros2pkg.verb.list:ListVerb’
from ros2pkg.api import get_package_names
from ros2pkg.verb import VerbExtension
class ListVerb(VerbExtension):
"""Output a list of available packages."""
def main(self, *, args):
for pkg_name in sorted(get_package_names()):
print(pkg_name) #打印出包名
get_package_names实现在ros2pkg/api/init.py 文件
def get_package_names():
return get_packages_with_prefixes().keys()
#定义在ros2下面install/lib/python3.6/site-packages/ament_index_python/packages.py文件里
def get_packages_with_prefixes():
"""
Return a dict of package names to the prefixes in which they are found.
:returns: dict of package names to their prefixes
:rtype: dict
"""
return get_resources('packages')
#install/lib/python3.6/site-packages/ament_index_python/resources.py
def get_resources(resource_type):
"""
Get the resource names of all resources of the specified type.
:param resource_type: the type of the resource
:type resource_type: str
:returns: dict of resource names to the prefix path they are in
:raises: :exc:`EnvironmentError`
"""
assert resource_type, 'The resource type must not be empty'
resources = {}
for path in get_search_paths():
resource_path = os.path.join(path, RESOURCE_INDEX_SUBFOLDER, resource_type)
if os.path.isdir(resource_path):
for resource in os.listdir(resource_path):
# Ignore subdirectories, and anything starting with a dot
if os.path.isdir(os.path.join(resource_path, resource)) \
or resource.startswith('.'):
continue
if resource not in resources:
resources[resource] = path
return resources