992 votes

Comment déterminer la taille d'un objet en Python ?

Je veux savoir comment obtenir la taille d'objets comme une chaîne de caractères, un entier, etc. en Python.

Question connexe : Combien d'octets par élément y a-t-il dans une liste (tuple) Python ?

J'utilise un fichier XML qui contient des champs de taille qui spécifient la taille de la valeur. Je dois analyser ce XML et faire mon codage. Lorsque je veux changer la valeur d'un champ particulier, je vais vérifier le champ de taille de cette valeur. Ici, je veux comparer si la nouvelle valeur que je vais entrer est de la même taille que dans le XML. Je dois vérifier la taille de la nouvelle valeur. Dans le cas d'une chaîne de caractères, je peux dire que c'est la longueur. Mais dans le cas d'un int, float, etc. Je ne comprends pas bien.

904voto

nosklo Points 75862

Il suffit d'utiliser le sys.getsizeof définie dans le sys module.

sys.getsizeof(object[, default]) :

Renvoie la taille d'un objet en octets. L'objet peut être n'importe quel type d'objet. Tous les objets intégrés renverront résultats corrects, mais cela ne doit pas pas forcément vrai pour les extensions extensions tierces, car il s'agit d'une implémentation spécifiques.

Seule la consommation de mémoire directement attribuée à l'objet est est comptabilisée, et non la consommation de mémoire des objets auxquels il fait référence.

El default permet de définir une valeur qui sera retournée si le type d'objet ne fournit pas de moyen de récupérer la taille et provoquerait un TypeError .

getsizeof appelle l'objet __sizeof__ et ajoute une surcharge supplémentaire au garbage collector si l'objet est géré par le collecteur d'ordures.

Ver recette récursive sizeof pour un exemple d'utilisation de getsizeof() récursivement pour trouver la taille des conteneurs et de tout leur contenu.

Exemple d'utilisation, dans python 3.0 :

>>> import sys
>>> x = 2
>>> sys.getsizeof(x)
24
>>> sys.getsizeof(sys.getsizeof)
32
>>> sys.getsizeof('this')
38
>>> sys.getsizeof('this also')
48

Si vous êtes sous python < 2.6 et que vous n'avez pas sys.getsizeof vous pouvez utiliser ce module complet à la place. Mais je ne l'ai jamais utilisé.

318 votes

Veuillez ajouter à l'avertissement que cela ne sera pas vrai pour les objets imbriqués ou les dicts imbriqués ou les dicts dans les listes, etc.

5 votes

Umm... sys.sizeof(c) est 32 même si l'instance de la classe a 50 attributs ! Il y a quelque chose qui cloche ! Essayez ceci : d = {k: v for k, v in zip('ABCDEFGHIJKLMNOPQRSTUVWXYabcdefghijklmnopqrstuvwxy', range(50))} class C(object): def __init__(self, **kwargs): _ = {setattr(self, k, v) for k, v in kwargs.items()} c = C(**d) sys.getsizeof(d) 1676 sys.getsizeof(c) 32

14 votes

@ChaimG c'est parce que chaque objet n'utilise que 32 octets ! !! Le reste est constitué de références à d'autres objets. Si vous voulez prendre en compte les objets référencés, vous devez définir les paramètres suivants __sizeof__ pour votre classe. La méthode intégrée dict La classe python le définit, c'est pourquoi vous obtenez le résultat correct lorsque vous utilisez un objet de type dict .

88voto

Mike Dewar Points 2208

Pour les tableaux numpy, getsizeof ne fonctionne pas - pour moi, il renvoie toujours 40 pour une raison quelconque :

from pylab import *
from sys import getsizeof
A = rand(10)
B = rand(10000)

Puis (en ipython) :

In [64]: getsizeof(A)
Out[64]: 40

In [65]: getsizeof(B)
Out[65]: 40

Mais heureusement :

In [66]: A.nbytes
Out[66]: 80

In [67]: B.nbytes
Out[67]: 80000

33 votes

>Tous les objets intégrés renverront des résultats corrects, mais cela ne doit pas être vrai pour les extensions tierces, car cela est spécifique à l'implémentation. docs.python.org/library/sys.html#sys.getsizeof

38 votes

"Si vous utilisez un tableau numpy ( docs.scipy.org/doc/numpy/reference/arrays.ndarray.html ), vous pouvez utiliser l'attribut 'ndarray.nbytes' pour évaluer sa taille en mémoire." stackoverflow.com/a/15591157/556413

20 votes

Je pense que 40 octets est correct, cependant getsizeof() ne vous donne que la taille de l'objet (l'en-tête du tableau), pas celle des données qu'il contient. Idem pour les conteneurs python où sys.getsizeof([1,2,4]) == sys.getsizeof([1,123**456,4]) == 48 alors que sys.getsizeof(123**456) = 436

16voto

Brian Points 48423

Cela peut être plus compliqué qu'il n'y paraît, selon la façon dont vous voulez compter les choses. Par exemple, si vous avez une liste de int vous souhaitez que la taille de la liste contenant les références à la int s ? (c'est-à-dire la liste seulement, et non ce qu'elle contient), ou voulez-vous inclure les données réelles pointées, auquel cas vous devez gérer les références dupliquées, et comment éviter le double comptage lorsque deux objets contiennent des références au même objet.

Vous voudrez peut-être jeter un coup d'œil à l'un des profileurs de mémoire python, tel que pysizer pour voir s'ils répondent à vos besoins.

7voto

alexey Points 154

Voici un script rapide que j'ai écrit sur la base des réponses précédentes pour lister les tailles de toutes les variables.

for i in dir():
    print (i, sys.getsizeof(eval(i)) )

0 votes

Ce n'est pas faux, c'est ambigu. sys.getsizeof retournera toujours la valeur si nécessaire, donc il n'y a pas besoin de perdre en performance avec try..except.

0 votes

Oh, c'est un bon point et je n'y ai pas pensé - le code dans la forme qu'il est maintenant montre juste comment il a été chronologiquement écrit - d'abord je connaissais numpy (donc nbytes), puis j'ai cherché une solution plus générique. Merci pour l'explication _/ \_

-7voto

Jeff Shannon Points 3439

Premièrement : une réponse.

import sys

try: print sys.getsizeof(object)
except AttributeError:
    print "sys.getsizeof exists in Python ≥2.6"

Discussion :
En Python, vous ne pouvez jamais accéder à des adresses mémoire "directes". Pourquoi, alors, auriez-vous besoin ou voudriez-vous savoir combien de ces adresses sont occupées par un objet donné ? C'est une question tout à fait inappropriée à ce niveau d'abstraction. Lorsque vous peignez votre maison, vous ne demandez pas quelles fréquences de lumière sont absorbées ou réfléchies par chacun des atomes constitutifs de la peinture, vous demandez simplement quelle est sa couleur - les détails des caractéristiques physiques qui créent cette couleur sont hors sujet. De même, le nombre d'octets de mémoire qu'un objet Python donné occupe n'a rien à voir avec le sujet.

Alors, pourquoi essayez-vous d'utiliser Python pour écrire du code C ? :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X