Je voudrais écrire un programme qui modifient les programmes de python ainsi:Puis-je utiliser python ast module pour cela?
changement
"une chaîne littérale%" % CHOSE
à
functioncall ("une chaîne littérale % ")% CHOSE
Merci,
Je voudrais écrire un programme qui modifient les programmes de python ainsi:Puis-je utiliser python ast module pour cela?
changement
"une chaîne littérale%" % CHOSE
à
functioncall ("une chaîne littérale % ")% CHOSE
Merci,
Vous pouvez résoudre ce d'avoir à écrire un programme. Au lieu de cela, utilisez simplement le meilleur éditeur jamais créé: Emacs. Ça vaut le coup d'apprendre si vous ne l'avez pas déjà fait. Avec cela, vous pouvez résoudre cela en utilisant sa capacité regex-replace. Le seul problème est que j'utilise rarement les regex, donc j'oublie toujours les détails de la syntaxe énigmatique et je dois toujours le chercher: P Je vais essayer de le comprendre à nouveau pour vous. Voici un lien vers la Search & Replace Info for Emacs - scroll down for using regex's
J'ai besoin d'un moyen de le faire de façon mélodramatique, donc je peux l'inclure dans un autre programme comme une sorte de préprocesseur. –
[Melodrama] (http://en.wikipedia.org/wiki/Melodrama) tiquement, hein? Mais si vous voulez faire du code, utilisez le module 're' de python pour gérer les expressions régulières. – JAB
Mélodramatiquement j'ai tapé? F * vérificateur d'orthographe. J'étais programmé. –
Il peut être plus simple avec tokenize - adapter l'exemple dans la documentation,
import cStringIO
import tokenize
class Lookahead(object):
def __init__(self, s):
self._t = tokenize.generate_tokens(cStringIO.StringIO(s).readline)
self.lookahead = next(self._t, None)
def __iter__(self):
return self
def next(self):
result = self.lookahead
if result is None: raise StopIteration
self.lookahead = next(self._t, None)
return result
def doit(s):
toks = Lookahead(s)
result = []
for toktype, tokvalue, _, _, _ in toks:
if toktype == tokenize.STRING:
pk = toks.lookahead
if pk is not None and pk[0] == tokenize.OP and pk[1] == '%':
result.extend([
(tokenize.NAME, 'functioncall'),
(tokenize.OP, '('),
(tokenize.STRING, repr(tokvalue)),
(tokenize.OP, ')')
])
continue
result.append((toktype, tokvalue))
return tokenize.untokenize(result)
print doit('"some literal string %" % SOMETHING')
Imprime functioncall ('"some literal string %"')%SOMETHING
. L'espacement est assez particulier (il faut beaucoup plus d'efforts pour obtenir l'espacement juste - mais c'est encore pire pour reconstruire des sources à partir d'un AST modifié), mais ça va bien si tout ce que vous allez faire est d'importer/exécuter le code résultant (pas si bien si vous voulez obtenir un code lisible et modifiable - mais c'est un assez gros problème que je suggère un Q séparé ;-).
Il semble y avoir des citations non désirées par rapport à ce que le PO demandait.Je crois que remplacer repr (tokvalue) par tokvalue donne le résultat désiré. –
Here est une autre question SO qui peut être utile.
Je suppose que le module ast
ne dispose pas d'un établissement pour revenir au code source, mais Armin Ronacher a écrit un module codegen qui met en œuvre une fonction to_source
pour faire juste que pour ast
nœuds.
Je n'ai pas essayé de le faire moi-même.
Le module codegen ne fonctionne pas pour chaque code python :( –
import re
pattern = r'(".+? %")(?= %)'
oldstr = '"some literal string %" % SOMETHING'
newstr = re.sub(pattern, r'functioncall(\1)', oldstr)
Essayez quelque chose comme ça. (Bien qu'avec le fichier I/O, bien sûr.) Je n'ai pas encore travaillé avec ast
, donc je ne sais pas si l'utiliser serait plus facile pour quelque chose comme ça, mais il me semble que si vous faites juste une simple recherche-remplacer et ne faites pas vraiment beaucoup d'analyse complexe alors il n'y a pas besoin d'utiliser ast
.
Vous pourriez avoir plus de chance en utilisant l'outil 2to3, qui est conçu pour les transformations source-à-source. –