2009-05-29 8 views
1

J'essaie de tester un caractère t/a ou un espace et je ne comprends pas pourquoi ce morceau de code ne fonctionnera pas. Ce que je fais est de lire dans un fichier, en comptant le loc pour le fichier, puis en enregistrant les noms de chaque fonction présente dans le fichier avec leurs lignes de code individuelles. Le bit de code ci-dessous est où j'essaie de compter la loc pour les fonctions.str.startswith() ne fonctionne pas comme je l'ai prévu

import re 

... 
    else: 
      loc += 1 
      for line in infile: 
       line_t = line.lstrip() 
       if len(line_t) > 0 \ 
       and not line_t.startswith('#') \ 
       and not line_t.startswith('"""'): 
        if not line.startswith('\s'): 
         print ('line = ' + repr(line)) 
         loc += 1 
         return (loc, name) 
        else: 
         loc += 1 
       elif line_t.startswith('"""'): 
        while True: 
         if line_t.rstrip().endswith('"""'): 
          break 
         line_t = infile.readline().rstrip() 

      return(loc,name) 

Sortie:

Enter the file name: test.txt 
line = '\tloc = 0\n' 

There were 19 lines of code in "test.txt" 

Function names: 

    count_loc -- 2 lines of code 

Comme vous pouvez le voir, mon test d'impression pour la ligne montre un/t, mais l'instruction if dit explicitement (ce que je pensais) qu'il ne doit exécuter avec aucun caractère d'espace présent.

Voici mon fichier test complet que j'utilise:

def count_loc(infile): 
    """ Receives a file and then returns the amount 
     of actual lines of code by not counting commented 
     or blank lines """ 

    loc = 0 
    for line in infile: 
     line = line.strip() 
     if len(line) > 0 \ 
     and not line.startswith('//') \ 
     and not line.startswith('/*'): 
      loc += 1 
      func_loc, func_name = checkForFunction(line); 
     elif line.startswith('/*'): 
      while True: 
       if line.endswith('*/'): 
        break 
       line = infile.readline().rstrip() 

    return loc 

if __name__ == "__main__": 
    print ("Hi") 
    Function LOC = 15 
    File LOC = 19 
+0

Ne pas publier de doublons (http://stackoverflow.com/questions/929169/str-startswith-not-working-as-i-intended). –

Répondre

8

\s est que des espaces à l'ensemble re lorsque vous faites correspondance de motif.

Pour startswith, une méthode ordinaire de chaînes ordinaires, \s n'a rien de spécial. Pas un motif, juste des caractères.

+0

J'utilise l'importation re - Je vais ajouter cela à l'article original – Justen

+1

@Justen Vous êtes en train d'importer re, mais vous n'utilisez que des méthodes de base de la chaîne – JimB

+0

Ah je vois, bien comme indiqué dans le mon commentaire dans le message ci-dessous , J'ai essayé \ t et '' mais il ne détecte pas le 'i' dans le if __name__ == ... donc il continue à compter la loc de la fonction jusqu'à ce que la fin du fichier soit atteinte. (btw, j'utilise regex ailleurs dans le prog, donc l'importation re est encore nécessaire) – Justen

2

Vos littéraux de chaîne ne sont pas ce que vous pensez qu'ils sont. Vous pouvez spécifier un espace ou TAB comme ceci:

space = ' ' 
tab = '\t' 
+0

J'ai essayé ça. J'ai changé mon code pour: sinon line.startswith ('\ t') et pas line.startswith (''): print ('line =' + repr (ligne)) return (loc, nom) et il doesn ne détecte pas la ligne if __name__ == '__main__' et ne compte que jusqu'à – Justen

3

Votre question a déjà répondu, ce qui est légèrement hors-sujet, mais ...

Si vous voulez analyser le code, il est souvent plus facile et moins sujet aux erreurs d'utiliser un analyseur. Si votre code est un code Python, Python est fourni avec deux parseurs (tokenize, ast, parser). Pour les autres langues, vous pouvez trouver beaucoup de parseurs sur Internet. ANTRL est un bien connu avec Python bindings.

À titre d'exemple, le couple suivant des lignes d'impression de code toutes les lignes d'un module Python qui ne sont pas des commentaires et pas de chaînes de doc-:

import tokenize 

ignored_tokens = [tokenize.NEWLINE,tokenize.COMMENT,tokenize.N_TOKENS 
       ,tokenize.STRING,tokenize.ENDMARKER,tokenize.INDENT 
       ,tokenize.DEDENT,tokenize.NL] 
with open('test.py', 'r') as f: 
    g = tokenize.generate_tokens(f.readline) 
    line_num = 0 
    for a_token in g: 
     if a_token[2][0] != line_num and a_token[0] not in ignored_tokens: 
      line_num = a_token[2][0] 
      print(a_token) 

Comme a_token ci-dessus est déjà analysé, vous pouvez facilement vérifier pour la définition de la fonction, aussi. Vous pouvez également suivre où la fonction se termine en regardant la colonne en cours commencer a_token[2][1]. Si vous voulez faire des choses plus complexes, vous devriez utiliser ast.

+0

+1 - n'a pas eu l'occasion de l'ajouter moi-même – JimB

Questions connexes