Python3.0 - tokenize und untokenize
-
06-09-2019 - |
Frage
Ich bin etwas mit ähnlich dem folgenden vereinfachten Skript-Schnipsel von Python aus einer größeren Datei zu analysieren:
import io
import tokenize
src = 'foo="bar"'
src = bytes(src.encode())
src = io.BytesIO(src)
src = list(tokenize.tokenize(src.readline))
for tok in src:
print(tok)
src = tokenize.untokenize(src)
Auch wenn der Code nicht gleich in Python2.x ist, verwendet es das gleiche Idiom und funktioniert gut. Um jedoch das obige Snippet mit python3.0 ausgeführt wird, ich diese Ausgabe erhalten:
(57, 'utf-8', (0, 0), (0, 0), '')
(1, 'foo', (1, 0), (1, 3), 'foo="bar"')
(53, '=', (1, 3), (1, 4), 'foo="bar"')
(3, '"bar"', (1, 4), (1, 9), 'foo="bar"')
(0, '', (2, 0), (2, 0), '')
Traceback (most recent call last):
File "q.py", line 13, in <module>
src = tokenize.untokenize(src)
File "/usr/local/lib/python3.0/tokenize.py", line 236, in untokenize
out = ut.untokenize(iterable)
File "/usr/local/lib/python3.0/tokenize.py", line 165, in untokenize
self.add_whitespace(start)
File "/usr/local/lib/python3.0/tokenize.py", line 151, in add_whitespace
assert row <= self.prev_row
AssertionError
Ich habe für Verweise auf diese Fehler und ihre Ursachen gesucht, aber nicht gelungen, irgendwelche zu finden. Was mache ich falsch und wie kann ich es beheben?
[Bearbeiten]
Nach dem partisann 's Beobachtung, dass eine neue Zeile an die Quelle Anfügen der Fehler weg gehen verursacht, begann ich mit Messing die folgende Liste ich war untokenizing. Es scheint, dass der EOF
Token einen Fehler verursacht, wenn nicht sofort so durch eine neue Zeile voran Entfernen sie dem Fehlers entledigt. Das folgende Skript läuft ohne Fehler:
import io
import tokenize
src = 'foo="bar"'
src = bytes(src.encode())
src = io.BytesIO(src)
src = list(tokenize.tokenize(src.readline))
for tok in src:
print(tok)
src = tokenize.untokenize(src[:-1])
Lösung
src = 'foo="bar"\n'
You Newline vergessen.
Andere Tipps
Wenn Sie den Eingang begrenzen auf die ersten zwei Elemente der Token untokenize
, scheint es zu funktionieren.
import io
import tokenize
src = 'foo="bar"'
src = bytes(src.encode())
src = io.BytesIO(src)
src = list(tokenize.tokenize(src.readline))
for tok in src:
print(tok)
src = [t[:2] for t in src]
src = tokenize.untokenize(src)