Afficher la valeur d'une variable/objet ?

mortel - Modifié le 28 mars 2024 à 15:23
mamiemando Messages postés 33081 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 27 avril 2024 - 28 mars 2024 à 15:42

Bonjour

Mon niveau python : débutant débutant

Sous python, j'ai ce code ci

def ScriptMain(script_data, reserved):
    print("type script_data :", type(script_data))
    print("script_data is:", script_data)

J'obtiens ce résultat :

type script_data : <class 'sdklib.ScriptData.ScriptData'>
script_data is: <sdklib.ScriptData.ScriptData object at 0x7fe1caf4d7f0>

À quoi correspond 0x7fe1caf4d7f0 ? Une adresse mémoire ?

Est-ce possible d'afficher la valeur brute de script_data ?

Est possible de copier tout le contenu de script_data dans une nouvelle variable ? (sous C, il suffisait de faire a = b, mais sous python ?)

Cordialement

3 réponses

Whismeril Messages postés 19030 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 27 avril 2024 931
27 mars 2024 à 17:53

Bonsoir

à l'instar de Java ou C# un objet dispose d'une méthode qui affiche sa description quand on la passe à print().

Quand cette méthode n'est pas codée spécialement pour une classe, c'est effectivement le type et l'emplacement mémoire qui sont affichés.

Pour afficher les attributs/propriétés de cet objet, il faut faire

print(monObjet.Attribut)

En python, le résultat de a = b dépend du type de b.

Si b est d'un type non mutable, alors la valeur est copiée, si b est d'un type mutable, alors c'est la référence qui est copiée.

Si tu n'es pas à l'aise avec les types mutables ou non, voir ici https://www.qwant.com/?q=les+types+mutables+en+python&client=brz-brave&t=web

Et pour le passage par référence ou valeur https://www.qwant.com/?client=brz-brave&q=difference+passage+par+r%C3%A9fence+et+passage+par+valeur&t=web


0
yg_be Messages postés 22731 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 27 avril 2024 1 477
Modifié le 28 mars 2024 à 15:24

bonjour,

En C, si b est un pointeur, a=b ne copie pas "tout le contenu".

En python, pour copier tout le contenu (ce qui n'est pas toujours souhaitable), tu peux utiliser le package copy:

import copy
a = [1, 2]
b = copy.deepcopy(a)
c = a
print(a, b, c)
a[0] = 3
print(a, b, c)
0
mamiemando Messages postés 33081 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 27 avril 2024 7 749
Modifié le 28 mars 2024 à 15:48

Bonjour,

Quelques précisions.

À quoi correspond 0x7fe1caf4d7f0 ? Une adresse mémoire ?

Oui. Cette adresse s'obtient à l'aide de la fonction id. Tu peux ensuite la convertir en hexadécimal si tu le souhaites avec la fonction hex :

print(hex(id(script_data))

Est-ce possible d'afficher la valeur brute de script_data ?

Ça dépend ce que tu appelles valeur_brute. Si c'est octet par octet, il faudrait lire la mémoire à cette endroit ce qui n'est pas forcément aisé ni utile en pratique.

Si tu parles d'une valeur compréhensible par un être humain, cela dépend si l'objet en question implémente les méthodes __repr__ et/ou __self__ :

class Object:
    def __init__(self):
        self.a = 1
        self.b = 2
    def __str__(self) -> str:
        return "STR:" + str(self.__dict__)
    def __repr__(self) -> str:
        return "REPR:" + repr(self.__dict__)

o = Object()

print(str(o))   # Affiche "STR:{'a': 1, 'b': 2}"
print(repr(o))  # Affiche "REPR:{'a': 1, 'b': 2}"
print(o)        # Affiche "STR:{'a': 1, 'b': 2}"

Dans ton cas, ScriptData ne surcharge visiblement pas ces méthodes et donc c'est l'affichage par défaut d'un objet qui est utilisé. Mais comme tu le vois dans l'extrait de code ci-dessous, si tu ne peux pas modifier le code de ScriptData, tu peux t'en sortir en convertissant cet objet sous forme d'un dictionnaire, et afficher ledit dictionnaire ;

print(script_data.__dict__)

Si l'objet scriptData est compliqué, il est recommandé de l'afficher plutôt avec pprint :

from pprint import pprint

pprint(script_data.__dict__)

Est possible de copier tout le contenu de script_data dans une nouvelle variable ? (sous C, il suffisait de faire a = b, mais sous python ?)

En python, les types de bases (int, float...) sont passés par copie. Les containers (set, dict, list, ...) et plus généralement les objets sont passés par référence (une référence étant une adresse mémoire qui pointe vers un objet valide).

Concernant les chaînes de caractères, il y a une subtilité. En effet, en python, le type str est dit immutable. Cela veut dire qu'on ne peut pas modifier une chaîne. Donc, quand tu modifies une chaîne, en réalité, tu en crées en réalité une nouvelle en mémoire (un peu comme en C, où tu devrais faire un realloc ; mais pas comme en C++ ou en Java, ou seul le buffer interne est réalloué en cas de besoin).

s = "abcd"
print(s, hex(id(s)))  # Affiche: "'abcd' une_adresse"
s += "e"
print(s, hex(id(s)))  # Affiche: "'abcde' une_autre_adresse"

Lorsque tu invoques l'opérateur =, l'objet est recopié dans le cas des types de base. Sinon, seule la référence est copiée.

l1 = [1, 2, 3]
l2 = l1
l1.append(4)
print(l1, l2) # Affiche [1, 2, 3, 4] [1, 2, 3, 4]

Donc, si tu veux que les deux instances soient indépendantes, il faut recopier l1 dans l2 avec copy.copy ou copy.deepcopy comme indiqué par yg_be dans #2. La nuance entre copy.copy et copy.deepcopy, c'est que la recopie est faite récursivement avec copy.deepcopy.

from copy import deepcopy

l3 = deepcopy(l1)
l3.append(5)
print(l1, l3)
[1, 2, 3, 4] [1, 2, 3, 4, 5]

Bonne chance

0