Erreur Nonetype sur une regexp pourtant reconnue [résolu] - Python - Programmation
Marsh Posté le 05-06-2009 à 17:05:38
Avant de passer au problème même, petites suggestions:
1. Poster du code python en utilisant la balise [ code=python] (en enlevant l'espace au début qui est là pour éviter que le forum ne me l'interprète et non la balise [ code] ou [ cpp], ça donne une coloration correcte:
Code :
|
vs
Code :
|
2. La PEP8 demande de ne pas mettre d'espaces entre les parentèses: def split(pattern, string) non def split( pattern, string ), o.search(string) et non o.search( string )
3. J'ai un peu de mal à voir l'intérêt de ta fonction split quand au pire elle fait ce que fait str.split et au mieux ce que fait re.split (accessoirement les rawstrings ne sont pas limités aux regexps...)
4. print permet de séparer les valeurs qu'on lui donne par des virgules, print temp.group(1), "\n", temp.group(2), "\n", temp.group(3) est quand même plus lisible.
Pour ton problème, il faudrait plus d'infos, parce que là c'est pas reproductible. Si tu utilises un vrai split ça donne quoi? Les données viennent d'où? Fichier? Il est possible de voir tout ou partie du fichier?
Là comme ça je dirais de vérifier que tu ne récupères pas une ligne vide, ça concorderait (pas d'affichage parce que ton "print entree" sauterait simplement à la ligne, puis pas de match, et donc tu te prends des AttributeError).
Quand à essayer de planquer l'erreur sous le tapis et continuer le traitement...
Accessoirement, je suggérerais en plus de:
5. améliorer ton nommage de variables, là c'est vraiment pas terrible
6. utiliser des named match groups (directive ?P)
7. après un match/search, toujours tester que quelque chose a été matché au lieu de continuer direct sur l'utilisation du MatchObject
Marsh Posté le 06-06-2009 à 12:21:51
Tout d'abord merci de t'intéresser au problème Masklinn.
J'essayerai de suivre tes suggestions. Je ne savais pas pour la virgule dans le print, ça m'a l'air effectivement d'être une bonne chose.
La raison de la fonction split est que j'avais lu (en cherchant à faire un split en python) ceci: http://mail.python.org/pipermail/p [...] 0465.html. Mais maintenant que je le relis, je crois comprendre qu'il ne mettait le code du split qu'à titre d'exemple, puisqu'il propose ensuite une utilisation de re.split. Hum.
Bref aucune raison valable finalement.
Pour ce qui est tester le split de re il faudra que j'attende lundi pour être sur mon environnement de travail. Mais pour la ligne vide c'est sûrement ça! Je peux pas tester maintenant mais ça expliquerait des affichages que j'ai eu lors de mes tests que je ne comprenait pas alors. (Je n'avais envisagé cette possibilité qui me paraît évidente maintenant que tu l'évoques)
En ce qui concerne les données, oui je les tire d'un fichier, que j'ai créé à partir des infos sur http://www.rcsb.org/pdb/home/home.do. Données publiques donc, pas de problème pour les montrer:
100d\"ID=SPM SMILES=C(CCNCCCN)CNCCCN NAME=SPERMINE\"\HEADER=DNA-RNA\TITLE=CRYSTAL STRUCTURE OF THE HIGHLY DISTORTED CHIMERIC DECAMER R(C)D(CGGCGCCG)R(G)-SPERMINE COMPLEX-SPERMINE BINDING TO PHOSPHATE ONLY AND MINOR GROOVE TERTIARY BASE-PAIRING
200l\"ID=BME SMILES=C(CS)O NAME=BETA-MERCAPTOETHANOL\ID=CL SMILES=[Cl-] NAME=CHLORIDEION\"\HEADER=HYDROLASE\TITLE=THERMODYNAMIC AND STRUCTURAL COMPENSATION IN "SIZE-SWITCH" CORE-REPACKING VARIANTS OF T4 LYSOZYME
300d\"ID=MN SMILES=[Mn+2] NAME=MANGANESE(II)ION\"\HEADER=RIBOZYME\TITLE=CAPTURING THE STRUCTURE OF A CATALYTIC RNA INTERMEDIATE: RNA HAMMERHEAD RIBOZYME, MN(II)-SOAKED
400d\"ID=5CM SMILES=CC1=CN(C(=O)N=C1N)[C@H]2C[C@@H]([C@H](O2)COP(=O)(O)O)O NAME=5-METHYL-2'-DEOXY-CYTIDINE-5'-MONOPHOSPHATE\"\HEADER=DNA\TITLE=THE INTRINSIC STRUCTURE AND STABILITY OF OUT-OF-ALTERNATION BASE PAIRS IN Z-DNA
101d\"ID=NT SMILES=Cn1cc(cc1C(=O)Nc2cc(n(c2)C)C(=O)NCCC(=N)N)NC(=O)CNC(=N)N NAME=NETROPSIN\ID=MG SMILES=[Mg+2] NAME=MAGNESIUMION\ID=CBR SMILES=C1[C@@H]([C@H](O[C@H]1N2C=C(C(=NC2=O)N)Br)COP(=O)(O)O)O NAME=5-BROMO-2'-DEOXY-CYTIDINE-5'-MONOPHOSPHATE\"\HEADER=DNA\TITLE=REFINEMENT OF NETROPSIN BOUND TO DNA: BIAS AND FEEDBACK IN ELECTRON DENSITY MAP INTERPRETATION
Je dirais que le code minimal (pour ceux qui veulent tester) doit être quelque chose dans le goût là:
Code :
|
Pour le named match groups, euh, je ne sais tout simplement pas ce que c'est, mais je promets de me renseigner sur le sujet.
Le nom de mes variables est la seule chose sur laquelle je ne promet rien (mais je ferais un peu plus d'efforts à l'avenir).
Marsh Posté le 06-06-2009 à 12:55:31
Dans la mesure où ce sont des données bio disponibles dans des formats relativement standard (je présume), tu as essayé de regarder s'il n'y avait pas déjà des libs capables d'en lire un ou 2 (genre scipy.io)?
Sinon, autres problèmes que je vis dans ton bout de code:
1. Reste cohérent dans ton nommage de variables, de préférence en anglais
2. Pas besoin de "readlines", les objets fichiers sont itérables en Python donc tu peux écrire directement
Code :
|
3.
Code :
|
ne sert à rien (aussi bien le ";" que le reste de la ligne)
4.
Code :
|
Tu pourrais te simplifier le boulot en écrivant:
Code :
|
histoire de ne pas avoir à échapper tes quotes et doubles quotes.
Accessoirement, tu peux mettre le rstrip directement dans le paramètre:
Code :
|
et par défaut rstrip enlève tout le whitespace (espaces, tabs, newlines), pas besoin de préciser newlines donc (sauf si tu veux garder les espaces mais bon...)
5. Les named matchgroup permettent de référencer une match par un nom plutôt que par un indice (de cette manière même si tu dois éditer ta regex et rajouter des matchgroups ça ne pète pas, et accessoirement c'est plus lisible):
Code :
|
cf documentation Python sur le module re.
Marsh Posté le 08-06-2009 à 16:10:10
Je parse des données que j'ai été cherché un peu partout sur le site en fait, donc aucun script n'existe pour les parser.
Sinon j'ai reformaté mes données dans un format plus simple (deux fichiers), le code en est d'autant plus clair, et surtout il marche en utilisant re.split.
C'est vrai qu'il faut faire attention en cas de reconnaissance d'expression en début ou en fin de string, parce que ça renvoie un string vide dans le tableau.
J'ai plus qu'à appliquer le tag résolu sur ce topic... quand j'aurai trouvé comment il faut faire.
(Edit, j'ai changé le titre... c'est tout ce que je dois faire ou y a t'il une procédure spéciale?)
Merci pour tous tes conseils Masklinn, j'appliquerai des named matchgroup à l'avenir.
Marsh Posté le 05-06-2009 à 16:29:49
Bonjour à tous!
C'est mon premier post sur un forum de ce type, alors dîtes moi si quelque chose ne va pas (j'ai survolé http://forum.hardware.fr/hfr/Progr [...] 0261_1.htm mais on sait jamais).
D'habitude un peu de recherche sur google suffit mais sur le cas que je rencontre, j'avoue être plus que perplexe.
Je m'explique:
Je rencontre une erreur du type: AttributeError: 'NoneType' object has no attribute 'group' , le genre d'erreur qui m'arrive quand mon expression régulière n'est pas correcte et que temp.group(x) n'est pas définit (exemple de reconnaissance: temp=re.match(r"^(.+)", ligne) ). Bon.
Sauf qu'ici...
me renvoye:
ID=SPM SMILES=C(CCNCCCN)CNCCCN NAME=SPERMINE
SPM
C(CCNCCCN)CNCCCN
SPERMINE
Traceback (most recent call last):
File "start_tanimoto_final.py", line 164, in <module>
myapp = StartQT4()
File "start_tanimoto_final.py", line 53, in __init__
self.charger_fichier_1()
File "start_tanimoto_final.py", line 86, in charger_fichier_1
print temp.group(1)+"\n"+temp.group(2)+"\n"+temp.group(3)
AttributeError: 'NoneType' object has no attribute 'group'
(La reconnaissance d'expression étant située dans la méthode charger_fichier_1 de la classe StartQT4)
Donc si je résume, il m'imprime bien mes valeurs, mais s'arrête parce qu'elles ne seraient pas définies...
La piste que je privilégie, si ça peut vous aider :
Je me demande si ça ne viendrait pas de la façon dont entree est définie, je m'explique:
entree est une variable temporaire, utilisée pour parser le tableau Ligand_info_temp
tableau crée par l'utilisation d'une méthode qui émule la fonction split de perl (fonction qui découpe un string selon un patern et qui renvoye un tableau):
Le code de la méthode split est le suivant:
Y aurait t'il quelque chose qui n'irait pas dans cette méthode?
Je me pose la question parce que quand je code en dur entree="ID=tralala SMILES=youpi NAME=youplaboum", l'expression régulière fonctionne correctement, et en plus aucune erreur n'a lieu.
Ou est ce que cela viendrait d'autre part? Dans le pire des cas, peut on forcer Python à continuer l'execution du script même en cas d'erreur, puisque finalement les valeurs reconnues par l'expression régulière sont celles que je veux? Merci d'avance pour votre aide.
Message édité par Fourgueule le 08-06-2009 à 16:11:44