Je lis, je lis un fichier binaire composé d'enregistrements que dans C ressembleraient à ceci: maintenant je suis capable de l'analyser dans un tuple avec 23 valeurs distinctes, mais Serait préférer si je pouvais utiliser Remarque: il existe de nombreux enregistrements consécutifs dans la chaîne lorsque J'appelle Mon code (dépouillé vers les pièces correspondantes): p> nomméTuple code> pour combiner les 20 premiers octets dans code> texte code> et les trois octets restants dans
index code>. Comment puis-je y parvenir? Fondamentalement au lieu d'un tuple de 23 valeurs, je préférerais avoir deux buples de valeurs de 20 et 3 de 20 et 3 respectivement et d'accéder à ceux-ci à l'aide d'un "nom naturel", c'est-à-dire au moyen de
namedTuple code>. P> P> Je suis actuellement en train d'utiliser le format
"20c3b" code> pour
structure.unpack_from () code>. p>
parse_text code>. P>
#!/usr/bin/env python
import sys
import os
import struct
from collections import namedtuple
def parse_text(data):
fmt = "20c3B"
l = len(data)
sz = struct.calcsize(fmt)
num = l/sz
if not num:
print "ERROR: no records found."
return
print "Size of record %d - number %d" % (sz, num)
#rec = namedtuple('rec', 'text index')
empty = struct.unpack_from(fmt, data)
# Loop through elements
# ...
def main():
if len(sys.argv) < 2:
print "ERROR: need to give file with texts as argument."
sys.exit(1)
s = os.path.getsize(sys.argv[1])
f = open(sys.argv[1])
try:
data = f.read(s)
parse_text(data)
finally:
f.close()
if __name__ == "__main__":
main()
3 Réponses :
Pourquoi ne pas avoir parse_text Utiliser la tranche de chaîne (données [: 20], données [20:]) pour attirer les deux valeurs, puis traiter chacun avec la structure? P>
ou prendre les 23 valeurs et les couper en deux? p>
Je dois manquer quelque chose. Peut-être souhaiterez-vous que cela se produise via le module de structure? P>
+1. Les données de chaîne sont là dans Data CODE> et il est trivial pour utiliser la tranchée pour sortir les deux chaînes de longueur fixe; Il n'est pas nécessaire d'utiliser
struct.unpack_from () code> pour obtenir des chaînes d'une chaîne.
struct code> est extrêmement précieux pour décompresser les valeurs entier et flotter, mais ici, nous avons juste des chaînes.
@steveha: Je n'ai pas besoin débalk_from code> même si je veux utiliser le décalage
code>? Rappelez-vous que c'est un exemple que j'ai réduit.
@ user1277476: la chaîne contient des enregistrements num code> (voir le code). C'est pourquoi j'utilisais
débalk_from code> en premier lieu. Bien sûr, la tranchée fonctionnerait également. Merci.
En fait, vous pouvez également utiliser struct code> si vous utilisez simplement
"20s" code> au lieu de
"20c" code>. Ensuite, vous obtenez une chaîne de longueur-20. Pourrait aussi bien faire cela au lieu de trancher. J'ai posté une réponse mais je vais le modifier pour le faire.
Selon les documents: http://docs.python.org/library/struct.html
Les champs non déballés peuvent être nommés en les attribuant à des variables ou en enveloppant le résultat dans un tuple nommé: P> blockQuote>
xxx pré> donc dans votre cas p>
xxx pré> trancher les variables de déballage peut-être un problème, si le format était
FMT = "20Si" code> ou quelque chose standard où nous ne retournons pas d'octets séquentiels, nous n'aurions pas besoin de le faire. P>
>>> import struct >>> from collections import namedtuple >>> data = "1"*24 >>> fmt = "20si" >>> Rec = namedtuple('Rec', 'text index') >>> r = Rec._make(struct.unpack_from(fmt, data)) >>> r Rec(text='11111111111111111111', index=825307441) >>>
AAAH, voir ... L'utilisation créative de la tranchée dans le _make code> appelait ce que j'avais manqué. Merci un tas. Je suivais les documents jusqu'à ce point, mais je n'ai pas compris comment faire cela sans variables supplémentaires. Je vais accepter dès que je peux, mais je ne peux pas uppoter avant minuit (épuisé tous les votes :)).
@ 0XC0000022L Pas de problème, bien que ce soit une douleur à trancher à cause des frais généraux, mais que je donne, je ne sais pas grand chose de votre situation, ce qui est le meilleur que je puisse trouver.
@Karlknechtel ouais je sais mais c'est dans les docs, et leur officiel donc je ne sais pas ...
Voici ma réponse. Je l'ai d'abord écrit à l'aide de la tranchée au lieu de Cette réponse utilise Je ne suis pas sûr de ce que vous voulez faire avec le légèrement difficile: la ligne comme aussi, nous pouvons utiliser un structure.unpack () code> mais @ samy.vilar a souligné que nous pouvons simplement utiliser le format "S" pour obtenir la chaîne. (J'aurais dû me rappeler que!)
structure.unpack () code> deux fois: une fois pour obtenir les chaînes, et une fois pour déballer la deuxième chaîne comme un entier. P>
"3b" code> article, mais je suppose que vous voulez décompresser cela comme un entier 24 bits. J'ai ajouté un 0 octet à la fin de la chaîne 3-Char et déballé comme un entier, au cas où vous voulez que vous voulez. P>
n, = struct.unpack (...) code> déballe une longueur-1 tuple dans une variable. En Python, la virgule fait le tuple, donc avec une virgule après un nom, nous utilisons le déballage de tuple pour déballer une longueur-1 tuple dans une seule variable. P>
avec CODE> Pour ouvrir le fichier, qui élimine le besoin du bloc code> code>. Nous pouvons également simplement utiliser
f.fin () code> pour lire le fichier entier en une fois, sans avoir à calculer la taille du fichier. P>
Merci, cette réponse a des concepts que j'ai lus dans le livre (apprentissage de Python) mais je ne me suis pas encore utilisé à peine.
Merci encore. Cette solution est brillante, en particulier la partie avec décodage de l'entier. Merci pour ça. Comme ma question était différente (dû, en partie, faute de connaissances), je pense que ce serait injuste accepter cette réponse. Cependant, j'ai activement tamisée à travers des autres réponses liées au Python et j'ai dépensé une partie de mon quota de vote quotidien. Merci encore!
data = str () code> (dans
principal code>) est inutile.