Je ne suis pas du tout familier avec Python, je fais habituellement Ruby ou JS. Mais je dois écrire un script d'analyse comparative sur un système qui exécute Python. Ce que j'essaie de faire est de créer un petit script qui obtient une taille de fichier et le nombre de threads et écrit un tampon aléatoire. C'est ce que j'ai obtenu après 2 heures de tripotage:
from multiprocessing import Pool
import os, sys
def writeBuf(buf):
def write(n):
f = open(os.path.join(directory, 'n' + str(n)), 'w')
try:
f.write(buf)
f.flush()
os.fsync(f.fileno)
finally:
f.close()
return write
if __name__ == '__main__':
targetDir = sys.argv[1]
numThreads = int(sys.argv[2])
numKiloBytes = int(sys.argv[3])
numFiles = int(102400 / numKiloBytes)
buf = os.urandom(numKiloBytes * 1024)
directory = os.path.join(targetDir, str(numKiloBytes) + 'k')
if not os.path.exists(directory):
os.makedirs(directory)
with Pool(processes=numThreads) as pool:
pool.map(writeBuf(buf), range(numFiles))
Mais il jette l'erreur: AttributeError: Can't pickle local object 'writeBuf.<locals>.write'
J'ai déjà essayé d'utiliser write
sans la fermeture, mais j'ai eu une erreur lorsque j'ai essayé de définir la fonction à l'intérieur de __name__ == '__main__'
partie. L'omission de if
entraîne également une erreur et j'ai lu qu'il était nécessaire que Pool
fonctionne.
Qu'est-ce qui est censé être juste un petit script transformé en une énorme épreuve, quelqu'un peut-il me montrer le bon chemin?
En théorie, python ne peut pas pickler les fonctions. (Pour plus de détails, voir Can't pickle Function )
En pratique, python pickles le nom et le module d'une fonction pour que le passage d'une fonction fonctionne. Dans votre cas cependant, la fonction que vous essayez de passer est une variable locale renvoyée par writeBuf
.
Au lieu:
writeBuf
.write
(buf
et directory
), mais donnez à write
tout ce dont elle a besoin comme paramètre.Résultat:
def write(args):
directory, buf, n = args
with open(os.path.join(directory, 'n' + str(n)), 'w') as f:
# might as well use with-statements ;)
f.write(buf)
f.flush()
os.fsync(f.fileno)
if __name__ == '__main__':
...
with Pool(processes=numThreads) as pool:
nargs = [(directory, buf, n) for n in range(numFiles)]
pool.map(write, nargs)