---
title: "ROS2. Añadiendo carpetas adicionales a nuestro paquete Python"
description: "En muchas ocasiones necesitamos añadir carpetas adicionales a las que inicialmente se generan cuando creamos un paquete Python. Por ejemplo es muy habitual incluir carpetas como launch o config. Sin embargo, si simplemente creamos dichas carpetas, estas no se incluirán de forma automática en la instalación del paquete al compilarlo.  Para ello hace falta modificar […]"
featured_image: "https://robotica-facil-con-ros2.es/wp-content/uploads/2022/07/id3181p-package-tree.png"
url: "https://robotica-facil-con-ros2.es/?p=3186"
date_modified: "2026-07-06T07:04:35+00:00"
---

En muchas ocasiones necesitamos añadir carpetas adicionales a las que inicialmente se generan cuando creamos un paquete Python. Por ejemplo es muy habitual incluir carpetas como *launch* o *config*.

Sin embargo, si simplemente creamos dichas carpetas, estas no se incluirán de forma automática en la instalación del paquete al compilarlo. 

Para ello hace falta modificar el archivo ***setup.py*** del mismo, concretamente la parte del código que afecta a la variable *data\_files*. 

data_files=[
        (&#039;share/ament_index/resource_index/packages&#039;, [&#039;resource/&#039; + package_name]),
        (&#039;share/&#039; + package_name, [&#039;package.xml&#039;]),
    ],

***data\_files*** especifica una lista de pares ***( directorio\_destino , \[ lista\_archivos \] )*** donde cada par indica el directorio de instalación y los archivos para instalar allí. Debe tenerse en cuenta que:

  - ***directorio\_destino*** es una ruta relativa al directorio de instalación *install* del espacio de trabajo.
  - ***lista\_archivos*** es una lista donde cada elemento es una ruta a un archivo relativa a la ubicación donde se encuentre *setup.py*.

Una forma de incorporar a la instalación por ejemplo todos los archivos *.yaml* que tenemos en una carpeta *config* es usar el comando *glob*, añadiendo la siguiente línea a *data\_files*: 

data_files=[
        (&#039;share/ament_index/resource_index/packages&#039;, [&#039;resource/&#039; + package_name]),
        (&#039;share/&#039; + package_name, [&#039;package.xml&#039;]),
        (os.path.join(&#039;share&#039;, package_name, &#039;config&#039;), glob(&#039;config/*.yaml&#039;)),
    ],

Sin embargo, si la carpeta *config* tuviera a su vez subcarpetas esta forma no nos sirve. 

A continuación se muestra cómo podemos modificar el archivo setup.py añadiendo una función, que he llamado ***package\_files***, a la cual le pasamos el contenido inicial de *data\_files* así como una lista con las carpetas que queramos incluir en la instalación y nos devuelve todos los pares *( directorio\_destino , \[lista\_archivos\] )* necesarios.

import os
from glob import glob
from setuptools import setup

package_name = &#039;check_joints&#039;

data_files=[
        (&#039;share/ament_index/resource_index/packages&#039;,
            [&#039;resource/&#039; + package_name]),
        (&#039;share/&#039; + package_name, [&#039;package.xml&#039;]),
    ]


def package_files(data_files, directory_list):

    paths_dict = {}

    for directory in directory_list:

        for (path, directories, filenames) in os.walk(directory):

            for filename in filenames:

                file_path = os.path.join(path, filename)
                install_path = os.path.join(&#039;share&#039;, package_name, path)

                if install_path in paths_dict.keys():
                    paths_dict[install_path].append(file_path)

                else:
                    paths_dict[install_path] = [file_path]

    for key in paths_dict.keys():
        data_files.append((key, paths_dict[key]))

    return data_files


setup(
    name=package_name,
    version=&#039;0.0.0&#039;,
    packages=[package_name],
    data_files=package_files(data_files, [&#039;config&#039;, &#039;launch&#039;]),
    install_requires=[&#039;setuptools&#039;],
    zip_safe=True,
    maintainer=&#039;ros&#039;,
    maintainer_email=&#039;ros@todo.todo&#039;,
    description=&#039;TODO: Package description&#039;,
    license=&#039;TODO: License declaration&#039;,
    tests_require=[&#039;pytest&#039;],
    entry_points={
        &#039;console_scripts&#039;: [
        ],
    },
)