1
votes

Problème de débogage des modules python dans VSCode

J'ai la structure de répertoires suivante pour mon projet d'entraînement python:

"module": "exercises.tough.${fileBaseNameNoExtension}"

Le extract_digits.py ressemble à ceci:

exercises
├── tough
|   | __init__.py
|   ├──ex1.py
|   ├──ex2.py
├── easy

Dans le armstrong_number.py j'ai ce qui suit:

"module" : "ds-and-algo.${fileBaseNameNoExtension}"

Depuis le répertoire racine du projet si j'exécute

{
"version": "0.2.0",
    "configurations": [
        {
            "name": "Python Module",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal",
            "pythonPath": "${config:python.pythonPath}",
            "module": "exercises.${fileBasenameNoExtension}",
            "cwd": "${workspaceRoot}",
            "env": {"PYTHONPATH":"${workspaceRoot}"}
        }
    ]
}

J'obtiens ModuleNotFoundError: aucun module nommé exercices

L'exécution de la virgule suivante avec l'indicateur -m résout le erreur:

python -m exercises.armstrong_number

Cependant, en utilisant VSCode afin de déboguer le fichier, j'ai la configuration de débogage suivante launch.json :

python exercises/armstrong_number.py

Cependant, cela pose quelques problèmes:

1) Pour un dossier différent, par exemple ds-and-algo , je dois modifier manuellement l'entrée du module dans la configuration de débogage du fichier launch.json sur

from .extract_digits import extract_digits

Au cas où j'aurais imbriqué configuration de dossier comme:

def extract_digits(n):
    pass

Je dois à nouveau modifier manuellement la configuration de débogage dans le fichier launch.json en: (compte tenu du cas du sous- dossier tough)

.
├── data
├── ds-and-algo
├── exercises
|   ├── __init__.py
│   ├── armstrong_number.py
│   ├── extract_digits.py
├── output

J'ai besoin d'implémenter un cas général où selon le fichier en cours de débogage, le "module" code > L'entrée du fichier launch.json doit être:

"module": "folder1.folder2.folder3 ..... foldern.script" code >

Tout comme fileBaseNameNoExtension , VSCode a quelques autres variables prédéfinies :

L'une des variables est relativeFile , qui est le chemin du fichier actuellement ouvert par rapport à workspaceFolder Donc pour le fichier ex1.py , la variable relativeFile sera exercises/tough/ex1.py.

I besoin de manipuler cette chaîne et de la convertir en exercices.tough.ex1 , ce qui est trivial si je peux écrire et exécuter la commande bash dans l'entrée "module" dans fichier launch.json . Mais je suis incapable de faire ça. Cependant, le lien variables prédéfinies dans VSCode a une section sur Commande variables , qui indique:

si les variables prédéfinies ci-dessus ne sont pas suffisantes, vous pouvez utiliser n'importe quelle commande VS Code comme variable via la $ {command: commandID} syntaxe.

Ce lien contient un tas d'autres informations qui peuvent être utiles. Je ne suis pas un expert en python, et je ne connais certainement pas de javascript, si c'est ce qui est nécessaire pour résoudre ce problème.


0 commentaires

3 Réponses :


0
votes

Je ne suis pas sûr d'exécuter des scripts bash, bien que s'il est possible d'exécuter JavaScript dans le fichier, "ds-and-algo. ($ {fileBaseNameNoExtension}). split ('/'). join ( '.') " devrait faire l'affaire.

En fait, la raison pour laquelle vous avez besoin de l'indicateur -m est que vous n'avez pas de fichiers __init__.py dans vos dossiers. Ces fichiers peuvent être vides, mais ils sont utilisés par python pour identifier une structure de module et permettre ainsi des importations imbriquées et relatives. J'espère que l'ajout de ces fichiers devrait vous permettre d'exécuter simplement exercices python / armstrong_number.py ou python ds-and-algo / dur / ex1.py


1 commentaires

J'ai déjà le fichier __init__.py dans les dossiers. Je suis désolé d'avoir oublié de mentionner cela dans l'arborescence. J'ai fait le montage maintenant. J'ai essayé les commandes split et join dans l'entrée de module du fichier launch.json . J'ai édité le fichier pour avoir `` `` module ":" $ {relativePath} .split ('/'). Join ('.') "` `` `Mais je pense qu'il exécute définitivement bash pour évaluer l'expression comme j'ai obtenu l'erreur suivante: `` bash: erreur de syntaxe près du jeton inattendu `(''` `



0
votes

Il n'y a pas de moyen de spécifier dans votre launch.json que vous voulez qu'il calcule le module que vous voulez déboguer. C'est parce qu'il est techniquement impossible de faire correctement 100% du temps en raison des packages d'espace de noms laissant n'importe quel répertoire représenter un package. Votre meilleure option est de créer des configurations de débogage distinctes par exemple que vous souhaitez exécuter dans votre launch.json (vous pouvez en avoir autant que vous le souhaitez). Si cela est trop fastidieux, vous pouvez écrire un script Python pour générer votre launch.json pour vous.


2 commentaires

Existe-t-il un moyen d'exécuter un script python en tant que tâche automatiquement dans VSCode, avant de commencer le débogage? Fondamentalement, je voudrais que l'entrée module dans le fichier launch.json soit différente dans chacun. Je pense que j'ai besoin de lire sur les paquets d'espace de noms pour vraiment comprendre où je me trompe.


@AbhishekBhatia pas que je sache. Vous pouvez écrire un script Python et configurer une tâche pour lui afin de pouvoir l'exécuter facilement à partir de VS Code. Et en fonction de l'effort que vous souhaitez y consacrer, vous pouvez créer un processus démon avec des observateurs de fichiers pour détecter automatiquement lorsqu'un changement se produit pour ensuite mettre à jour automatiquement launch.json . Mais cela pourrait être un peu trop de travail pour un problème ponctuel. :)



4
votes

Je ne peux pas reproduire votre erreur: ModuleNotFoundError: aucun module nommé Exercices .

Utilisation des fichiers suivants

Exercices / extract_digits.py code >

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Python: Module CmdVar",
      "type": "python",
      "request": "launch",
      "console": "integratedTerminal",
      "module": "${command:extension.commandvariable.file.relativeDirDots}.${fileBasenameNoExtension}",
    }
  ]
}

exercices / armstrong_number.py

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Exercise",
      "type": "python",
      "request": "launch",
      "console": "integratedTerminal",
      "module": "exercises.${fileBasenameNoExtension}",
    },
    {
      "name": "Exercise.Easy",
      "type": "python",
      "request": "launch",
      "console": "integratedTerminal",
      "module": "exercises.easy.${fileBasenameNoExtension}",
    },
    {
      "name": "DS",
      "type": "python",
      "request": "launch",
      "console": "integratedTerminal",
      "module": "ds.${fileBasenameNoExtension}",
    }
  ]
}

Si vous utilisez Python3 modifiez l'impression instruction en: print (armstrong_number (3)) et changez l'interpréteur Python utilisé.

Si votre répertoire actuel est le répertoire racine du projet et que vous exécutez

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Python: Current File",
      "type": "python",
      "request": "launch",
      "program": "${file}",
      "console": "integratedTerminal",
    }
  ]
}

Vous obtenez le numéro 10 dans la console


Dans Visual Studio Code, vous utilisez la mauvaise configuration de lancement.

Vous exécutez simplement des programmes python, vous devez donc utiliser la configuration Python: Current File . launch.json

python exercises/armstrong_number.py
  1. Ouvrez l'exemple de fichier py que vous souhaitez exécuter / déboguer, quel que soit son répertoire.
  2. Ou en faire le fichier actuel
  3. Sélectionnez la barre latérale de débogage
  4. Sélectionnez la configuration Python: Fichier actuel
  5. Cliquez sur le triangle "vert".

Maintenant, une commande compliquée est construite et exécutée. Il définira le CWD sur le répertoire du fichier courant et démarrera le débogueur sur le fichier courant.


Si vous vraiment avez besoin du lancement du module, vous pouvez utiliser un Espace de travail multi-racine dans VSC et avoir un launch.json configuré distinct pour chacun des répertoires racine


Si vous souhaitez utiliser la syntaxe $ {command: commandID} , vous pouvez construire une extension simple qui utilise activeTextEditor et construire une chaîne basée sur le nom du fichier


Une autre option consiste à utiliser des configurations de lancement multiples.

J'ai supprimé les propriétés où la valeur par défaut fonctionne ou qui ne sont pas utilisées.

from extract_digits import extract_digits

def armstrong_number(n):
  return extract_digits(n)

if __name__ == "__main__": 
  print armstrong_number(3)


Vous pouvez utiliser l'extension Variable de commande pour obtenir ce répertoire relatif avec un point séparateur.

def extract_digits(n):
  return 10


3 commentaires

Mon armstrong_number.py a un point (.) Avant le module d'importation comme ceci: python from .extract_digits import extract_digits , donc, python exercices / armstrong_number.py , donne ce qui suit erreur: `` ModuleNotFoundError: Aucun module nommé ' main .extract_digits'; ' main ' n'est pas un package Je ne veux pas qu'ils agissent comme des scripts indiv mais un module faisant partie d'un espace de travail de projet unique. J'utilise la configuration de fichier actuelle, mais c'est pour les scripts uniques. Pas dans un projet. activeTextEditor``` et $ {command: commandID} semblent être ce dont j'ai vraiment besoin. Mais je ne sais pas vraiment comment.


@AbhishekBhatia Une autre option est: Configurations de lancement multiples. Voir ma modification


Cela fonctionne vraiment! Merci! Je pense que c'est une très nouvelle extension, car j'ai dû mettre à jour vscode de 1.36 à 1.37, pour pouvoir l'installer.