2009-11-03 33 views
0

Hier j'ai demandé (« Un cas de listes d'ensembles se comportent différemment en Python 2.5 (je pense à l'extérieur égale ...) ») pourquoi la liste W construit comme suit:Existe-t-il un moyen d'inspecter les structures internes (différentes) des objets Python qui testent comme égal (==)?

r_dim_1_based = range(1, dim + 1) 
set_dim_1_based = set(r_dim_1_based) 

def listW_fill_func(val): 
    if (val == 0): 
     return set_dim_1_based 
    else: 
     return set([val]) 

W = [ listW_fill_func(A[cid]) 
      for cid in r_ncells ] 

ne se comportait pas comme je m'y attendais. En particulier, il ne se comportait pas comme les autres listes qui montraient une égalité avec lui (another_list == W -> True).

Y a-t-il un utilitaire, une astuce, un builtin, tout ce qui m'aurait montré ces différentes structures internes? Quelque chose qui aurait produit peut-être une déclaration C-like des objets de sorte que j'aurais vu immédiatement que j'avais affaire à des pointeurs dans un cas (liste W) et des valeurs dans les autres?

+0

Je ne comprends pas encore la question. Python fait tout avec des objets. Toute liste est une collection de références à des objets. Lorsque vous comparez deux listes, si elles ont la même longueur, et si chacun de leurs objets respectifs renvoie égal lors de la comparaison, les listes retournent égales. Python a aussi un opérateur 'is' qui vérifie l'identité de l'objet; peut-être pouvez-vous utiliser 'is' pour inspecter les choses afin de mieux comprendre ce qui se passe. – steveha

+0

@steveha: Coupable d'appeler une copie superficielle d'un objet une 'valeur' ​​et une référence à l'objet original un 'pointeur'. Le point de la question est dans votre quatrième phrase: "si" je suis allé et ai fait toutes ces choses, alors, oui, je pouvais voir que deux objets qui semblaient égaux (par ==) étaient différents, mais c'est trop comme le travail. Je désire un outil de débogage de sorte que dans une seconde ou deux je peux avoir les différences montrées à moi. Graphique, quelque chose comme les spécifications pour une structure C, par ex. --- – behindthefall

Répondre

1

Vous avez affaire à des références dans chaque cas (plus similaire aux pointeurs qu'aux valeurs). Vous pouvez certainement introspect références au contenu de votre cœur de vos objets - par exemple, si vous avez une liste et que vous voulez vérifier si tous les éléments sont des références identiques,

if len(thelist) != len(set(id(x) for x in thelist)): ... 

Notez que nous parlons de références ici - donc, deux références identiques à None, ou deux références identiques à la valeur int17, déclencheraient également la même alarme. Bien sûr, vous pouvez garder pour enlever introspectant ce cas, l'élimination immutables de la liste dans un premier passage, par exemple, si vous pensez que plusieurs références à la même immuable sont très bien - par exemple:

immutyps = int, long, float, tuple, frozenset, str, unicode 
mutables = [x for x in thelist if not isinstance(x, immutyps)] 
if len(mutables) != len(set(id(x) for x in mutables)): 
    cryhavocandletloosethedogsofwar() 

mais je questionner le retour sur investissement d'une stratégie d'introspection aussi profonde!

+0

Salut à nouveau, Alex. Je me demandais s'il y avait un moyen facile de nourrir un objet à un petit moteur et de récupérer un graphique ou quelque chose comme C-déclaration qui a montré ce que l'architecture de l'objet. En se référant à l'exemple d'hier, si j'avais ajouté les listes W1, W2 et W3 au moteur, j'aurais vu que dans W3, tous les items "inconnus" étaient des références (pointeurs) à la même variable, alors que dans les listes W1 et W2, ces éléments étaient vraiment les ensembles indépendants que je les imaginais être. – behindthefall

+0

Ack. Comment éditer un commentaire? Collez un verbe à la fin de cette première phrase. – behindthefall

+0

Mais je dois dire que votre première déclaration est un gardien, et je vais essayer de se souvenir de id(). – behindthefall