Compartir a través de


Creación y administración de proyectos y bibliotecas personalizadas

En este artículo, aprenderá a crear, administrar y compartir proyectos. Un proyecto es una estructura de carpetas con varios archivos que pueden acceder entre sí a las operaciones y funciones del otro. Los proyectos le ayudan a organizar lógicamente el código fuente. También puede usar proyectos como bibliotecas personalizadas a las que puede acceder desde orígenes externos.

Requisitos previos

Para ejecutar programas de Python, también necesita lo siguiente:

  • Un entorno de Python con Python y Pip instalado.

  • La biblioteca qdkPython con la azure adicional.

    python -m pip install --upgrade "qdk[azure]"
    

Cómo funcionan los proyectos

Un proyecto contiene un archivo de manifiesto denominado 'nombre', y uno o más archivos y carpetas en una estructura especificada. Puede crear un proyecto manualmente o directamente en .

Al abrir un archivo o en , el compilador busca en la jerarquía de carpetas circundantes el archivo de manifiesto y determina el ámbito del proyecto. Si el compilador no encuentra un archivo de manifiesto, el compilador funciona en un modo de archivo único.

Al establecer el en un archivo /> , el compilador busca el archivo de manifiesto en la carpeta .

Un proyecto de Q# externo es un proyecto estándar Q# que se encuentra en otro directorio o en un repositorio de GitHub público y actúa como una biblioteca personalizada. Un proyecto externo usa instrucciones para definir las funciones y las operaciones a las que pueden acceder los programas externos. Los programas definen el proyecto externo como una dependencia en su archivo de manifiesto y usan instrucciones para tener acceso a los elementos del proyecto externo, como operaciones, funciones, estructuras y espacios de nombres. Para obtener más información, consulte Uso de proyectos como dependencias externas.

Definición de un proyecto

Un proyecto se define mediante la presencia de un archivo de manifiesto y una carpeta, ambos deben estar en la carpeta raíz del proyecto. La carpeta contiene los archivos de origen. En el caso de programas y proyectos externos, el compilador detecta automáticamente la carpeta del proyecto. Para Python programas y Jupyter Notebook archivos, debe especificar la carpeta del proyecto Q# mediante una llamada qsharp.init. Sin embargo, la estructura de carpetas de un proyecto es la misma para todos los tipos de programas.

Estructura y jerarquía de carpetas de un proyecto.

Definir la carpeta del proyecto para programas

Al abrir un archivo en , el compilador busca hacia arriba en la estructura de carpetas de un archivo de manifiesto. Si el compilador encuentra un archivo de manifiesto, el compilador incluye todos los archivos del directorio y sus subdirectorios. Los elementos definidos en cada archivo están disponibles para todos los demás archivos del proyecto.

Por ejemplo, considere la siguiente estructura de carpetas:

  • Proyecto_de_teleportación
    • qsharp.json
    • src
      • Main.qs
      • TeleportOperations
        • TeleportLib.qs
        • PrepareState
          • PrepareStateLib.qs

Al abrir el archivo , el compilador hace lo siguiente:

  1. Comprueba para .
  2. Comprueba para .
  3. Comprueba para .
  4. Verifica y encuentra el archivo.
  5. Establece como directorio raíz del proyecto, e incluye todos los archivos y ficheros bajo el directorio en el proyecto. Si el archivo de manifiesto.

Nota:

Si incluyes referencias explícitas a las rutas de acceso de archivo en , el compilador carga los archivos y no pasa por el proceso de detección automática. Las referencias explícitas de ruta de acceso de archivo solo son necesarias cuando se define una biblioteca que se puede cargar desde una referencia de Git.

Crear un archivo de manifiesto

Un archivo de manifiesto es un archivo JSON denominado que puede incluir campos opcionales , y . El archivo de manifiesto mínimo viable es la cadena . Al crear un proyecto en , se crea un archivo de manifiesto mínimo automáticamente.

{}

Ejemplos de archivos manifest

En los ejemplos siguientes se muestra cómo definen los archivos de manifiesto el ámbito del proyecto.

  • En este ejemplo, es el único campo especificado, por lo que todos los archivos de este directorio y sus subdirectorios se incluyen en el proyecto.

    {
        "author":"Microsoft"
    }
    
  • Dentro de un proyecto, también puede usar el archivo de manifiesto para ajustar la configuración de Linter. De forma predeterminada, las tres reglas de Linter son:

    • : valor predeterminado =

    • : valor predeterminado =

    • : valor predeterminado =

      Puede establecer cada regla en el archivo de manifiesto en , o . Por ejemplo:

      {
          "author":"Microsoft",
          "lints": [
              {
                "lint": "needlessParens",
                "level": "allow"
              },
              {
                "lint": "redundantSemicolons",
                "level": "warn"
              },
              {
                "lint": "divisionByZero",
                "level": "error"
              }
            ]
      }
      
  • También puede usar el archivo de manifiesto para definir un proyecto externo como una dependencia y acceder de forma remota a las operaciones y funciones de ese proyecto externo. Para obtener más información, consulte Uso de proyectos como dependencias externas.

requisitos y propiedades del proyecto

Los siguientes requisitos y configuraciones se aplican a todos los proyectos.

  • Todos los archivos que desea incluir en el proyecto deben estar en una carpeta denominada , que debe estar en la carpeta raíz del proyecto. Al crear un proyecto en , la carpeta se crea automáticamente.

  • El archivo de manifiesto debe estar en el mismo nivel que la carpeta. Al crear un proyecto en , se crea automáticamente un archivo de manifiesto mínimo.

  • Use instrucciones para hacer referencia a operaciones y funciones de otros archivos del proyecto.

    import MyMathLib.*;  //imports all the callables in the MyMathLib namespace
    
    ...
    
    Multiply(x,y);
    

    O bien, haga referencia a ellos individualmente con el espacio de nombres .

    MyMathLib.Multiply(x,y); 
    

Solo para proyectos

  • Puede definir una operación de punto de entrada solo en un archivo en un proyecto , que es la operación por defecto.
  • Debe colocar el archivo con la definición de punto de entrada en un nivel de directorio del proyecto por debajo del archivo de manifiesto.
  • Todas las operaciones y funciones del proyecto que se almacenan en caché a partir de una pantalla se muestran como texto predictivo en .
  • Si aún no se importa el espacio de nombres de una operación o función seleccionada, agrega automáticamente la instrucción necesaria .

Creación de un proyecto

Para crear un proyecto, siga estos pasos:

  1. En el explorador de archivos, vaya a la carpeta que desea usar como carpeta raíz del proyecto.

  2. Abra el menú Ver y elija Paleta de comandos.

  3. Presione Enter: Crear proyecto. crea un archivo de manifiesto mínimo en la carpeta y agrega una carpeta con un archivo de plantilla.

  4. Edite el archivo de manifiesto del proyecto. "Consulte los ejemplos de archivos de manifiesto."

  5. Agregue y organice los archivos de origen en la carpeta .

  6. Si accede al proyecto desde un programa Python o Jupyter Notebook, establezca la ruta de acceso de la carpeta raíz con qsharp.init. En este ejemplo se supone que el programa está en la carpeta del proyecto:

    qsharp.init(project_root = '../Teleportation_project')
    
  7. Si solo usa archivos en , el compilador busca un archivo de manifiesto al abrir un archivo y determina la carpeta raíz del proyecto. A continuación, el compilador examina y sus subdirectorios en busca de y archivos .

Nota:

Puede crear manualmente el archivo de manifiesto y la carpeta en su lugar.

Proyecto de ejemplo

Este programa de teleportación cuántica es un ejemplo de proyecto que se ejecuta en el simulador local en . Para ejecutar el programa en Azure Quantum hardware o simuladores de terceros, consulte Comience con los programas Q# y VS Code para obtener los pasos de compilación de su programa y de conexión a su espacio de trabajo Azure Quantum.

Este ejemplo tiene la siguiente estructura de directorios:

  • Proyecto_de_Teletransportación
    • qsharp.json
    • src
      • Main.qs
      • TeleportOperations
        • TeleportLib.qs
        • PrepareState
          • PrepareStateLib.qs

El archivo de manifiesto contiene los campos de autor y licencia :

{
    "author":"Microsoft",
    "license":"MIT"
}

archivos de origen

El archivo principal contiene el punto de entrada y hace referencia al espacio de nombres de .

    import TeleportOperations.TeleportLib.Teleport; // references the Teleport operation from TeleportLib.qs

    operation Main() : Unit {
        use msg = Qubit();
        use target = Qubit();

        H(msg);
        Teleport(msg, target); // calls the Teleport() operation from TeleportLib.qs
        H(target);

        if M(target) == Zero {
            Message("Teleported successfully!");
        
        Reset(msg);
        Reset(target);
        }
    }

El archivo define la operación y llama a la operación desde el archivo .

    import TeleportOperations.PrepareState.PrepareStateLib.*; // references the namespace in PrepareStateLib.qs
 
    operation Teleport(msg : Qubit, target : Qubit) : Unit {
        use here = Qubit();

        PrepareBellPair(here, target); // calls the PrepareBellPair() operation from PrepareStateLib.qs
        Adjoint PrepareBellPair(msg, here);

        if M(msg) == One { Z(target); }
        if M(here) == One { X(target); }

        Reset(here);
    }

El archivo contiene una operación reutilizable estándar para crear un par bell.

    operation PrepareBellPair(left : Qubit, right : Qubit) : Unit is Adj + Ctl {
        H(left);
        CNOT(left, right);
    }

Ejecución de los programas

Elija la pestaña del entorno en el que ejecuta el programa.

Para ejecutar este programa, abra el archivo en y elija Ejecutar.

Configurar proyectos como dependencias externas

Puede configurar proyectos como una dependencia externa para otros proyectos, de forma similar a una biblioteca, para que las funciones y las operaciones del proyecto externo estén disponibles para otros proyectos. Una dependencia externa puede residir en un recurso compartido de disco o publicarse en un repositorio público de GitHub.

Para usar un proyecto como dependencia externa, debe:

  • Agregue el proyecto externo como dependencia en el archivo de manifiesto del proyecto que llama.
  • Si el proyecto externo se publica en GitHub, agregue la propiedad files al archivo de manifiesto del proyecto externo.
  • Agregue declaraciones al proyecto externo.
  • Agregue declaraciones al proyecto que lo llama.

Configurar los archivos de manifiesto

Los proyectos Q# externos pueden ubicarse en una unidad local o en un recurso compartido de red, o puede publicarlos en un repositorio público de GitHub.

El archivo de manifiesto del proyecto que realiza la llamada

Para agregar una dependencia a un proyecto externo en una unidad compartida, defina la dependencia en el archivo de manifiesto del proyecto que hace la llamada.

{
    "author": "Microsoft",
    "license": "MIT",
    "dependencies": {
        "MyDependency": {
            "path": "/path/to/project/folder/on/disk"
        }
    }
}

En el archivo de manifiesto anterior, es una cadena definida por el usuario que identifica el espacio de nombres al llamar a una operación. Por ejemplo, si crea una dependencia denominada , puede llamar a una función desde esa dependencia con .

Para agregar una dependencia a un proyecto publicado en un repositorio de GitHub público, use el siguiente archivo de manifiesto de ejemplo:

{
    "author": "Microsoft",
    "dependencies": {
        "MyDependency": {
            "github": {
                "owner": "GitHubUser",
                "repo": "GitHubRepoName",
                "ref": "CommitHash",
                "path": "/path/to/dependency"
            }
        }
    }
}

Nota:

Para las dependencias de GitHub, ref hace referencia a un GitHub refspec. recomienda usar siempre un hash de confirmación para que puedas confiar en una versión específica de tu dependencia.

El archivo de manifiesto del proyecto externo

Si el proyecto externo Q# se publica en un repositorio de GitHub público, debe agregar la propiedad files al archivo de manifiesto del proyecto externo, incluidos todos los archivos que usa el proyecto.

{
    "author": "Microsoft",
    "license": "MIT",
    "files": [ "src/MyMathFunctions.qs", "src/Strings/MyStringFunctions.qs" ]
}

La propiedad es opcional para un proyecto externo que se importa a través de una importación basada en una ruta de archivo local. La propiedad files solo es necesaria para los proyectos que se publican en GitHub.

Use la instrucción

Para que las funciones y las operaciones de un proyecto externo sean accesibles para los proyectos que llaman, use la instrucción . Puede exportar cualquiera o todos los elementos invocables en el archivo. No puede usar la sintaxis de caracteres comodín, por lo que debe especificar cada invocable que quiera exportar.

operation Operation_A() : Unit {
...
}
operation Operation_B() : Unit  {
...
}

// makes just Operation_A available to calling programs
export Operation_A;

// makes Operation_A and Operation_B available to calling programs 
export Operation_A, Operation_B, etc.; 

// makes Operation_A available as 'OpA'
export Operation_A as OpA;

Use la instrucción

Para que los elementos de una dependencia externa estén disponibles, use instrucciones del programa de llamada. La instrucción usa el espacio de nombres que se define para la dependencia en el archivo de manifiesto.

Por ejemplo, considere la dependencia en el siguiente archivo de manifiesto:

{
    "author": "Microsoft",
    "license": "MIT",
    "dependencies": {
        "MyMathFunctions": {
            "path": "/path/to/project/folder/on/disk"
        }
    }
}

Importe los invocables con el código siguiente:

import MyMathFunctions.MyFunction;  // imports "MyFunction()" from the namespace

...

La instrucción también admite la sintaxis y los alias de comodín.

// imports all items from the "MyMathFunctions" namespace
import MyMathFunctions.*; 

// imports the namespace as "Math", all items are accessible via "Math.<callable>"
import MyMathFunctions as Math;

// imports a single item, available in the local scope as "Add"
import MyMathFunctions.MyFunction as Add;

// imports can be combined on one line
import MyMathFunctions.MyFunction, MyMathFunctions.AnotherFunction as Multiply; 

Proyecto externo de ejemplo

En este ejemplo, use el mismo programa de teletransportación que el ejemplo anterior, pero separe el programa de llamada y los invocables en proyectos diferentes.

  1. Cree dos carpetas en la unidad local, por ejemplo , y .

  2. Cree un proyecto en cada carpeta. Para obtener más información, consulte los pasos descritos en Creación de un proyecto.

  3. En , el programa que realiza la llamada, copie en el archivo de manifiesto el código siguiente, pero edite la ruta según sea necesario para .

    {
      "author": "Microsoft",
      "license": "MIT",
      "dependencies": {
        "MyTeleportLib": {
          "path": "/Project_B" 
          }
        }
      }    
    
  4. En , copie el código siguiente en :

    import MyTeleportLib.Teleport; // imports the Teleport operation from the MyTeleportLib namespace defined in the manifest file
    
    operation Main() : Unit {
        use msg = Qubit();
        use target = Qubit();
    
        H(msg);
        Teleport(msg, target); // calls the Teleport() operation from the MyTeleportLib namespace
        H(target);
    
        if M(target) == Zero {
            Message("Teleported successfully!");
    
        Reset(msg);
        Reset(target);
        }
    }   
    
  5. En , copie el código siguiente en :

        operation Teleport(msg : Qubit, target : Qubit) : Unit {
            use here = Qubit();
    
            PrepareBellPair(here, target); 
            Adjoint PrepareBellPair(msg, here);
    
            if M(msg) == One { Z(target); }
            if M(here) == One { X(target); }
    
            Reset(here);
        }
    
        operation PrepareBellPair(left : Qubit, right : Qubit) : Unit is Adj + Ctl {
            H(left);
            CNOT(left, right);
        }
    
        export Teleport;       //  makes the Teleport operation available to external programs
    

    Nota:

    No es necesario exportar la operación si tu programa no llama directamente a esa operación. La operación ya es accesible por la operación porque está en el ámbito local de .

  6. Para ejecutar el programa, abra en y elija Ejecutar.

Proyectos y espacios de nombres implícitos

En los proyectos, si no especifica un espacio de nombres en un programa, el compilador usa el nombre de archivo como espacio de nombres. A continuación, cuando se hace referencia a un invocable desde una dependencia externa, se usa la sintaxis . Sin embargo, si el archivo se denomina , el compilador asume que el espacio de nombres y la sintaxis que realiza la llamada es . Por ejemplo: .

Dado que es posible que tenga varios archivos de proyecto, debe tener en cuenta la sintaxis correcta al hacer referencia a los invocables. Por ejemplo, considere un proyecto con la siguiente estructura de archivos:

  • /Fuente
    • Main.qs
    • MathFunctions.qs

El código siguiente realiza llamadas a la dependencia externa:

import MyTeleportLib.MyFunction;        // "Main" namespace is implied

import MyTeleportLib.MathFunctions.MyFunction;   // "Math" namespace must be explicit 

Para obtener más información sobre el comportamiento del espacio de nombres, consulte Espacios de nombres de usuario.