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