Derniers messages sur Zeste de Savoirhttps://zestedesavoir.com/forums/2021-10-01T14:28:04+02:00Les derniers messages parus sur le forum de Zeste de Savoir.noms, PyObjects, et identification, message #2379002021-10-01T14:28:04+02:00adri1/@adri1https://zestedesavoir.com/forums/sujet/15734/noms-pyobjects-et-identification/?page=1#p237900<p>Au passage, faire ça :</p>
<div class="hljs-code-div hljs-code-python"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span></div><pre><code class="hljs language-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Outer</span>():</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, msg: <span class="hljs-built_in">str</span>, nested_obj = Inner(<span class="hljs-params"></span>)</span>):</span>
self.msg = msg
self.nested_obj = nested_obj
</code></pre></div>
<p>est une erreur classique de débutant (qui, bien franchement, vient d’un problème de design du langage). Il ne faut <em>jamais</em> mettre un mutable comme argument par défaut. Les valeurs des arguments par défaut ne sont évalués qu’une seule fois, ce qui conduit à ce genre de problèmes :</p>
<div class="hljs-code-div hljs-code-python"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span><span data-count="5"></span><span data-count="6"></span><span data-count="7"></span><span data-count="8"></span><span data-count="9"></span><span data-count="10"></span><span data-count="11"></span></div><pre><code class="hljs language-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Outer</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, inner=[]</span>):</span>
self.inner = inner
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
outer_a = Outer()
outer_b = Outer()
outer_a.inner.append(<span class="hljs-number">3</span>)
<span class="hljs-built_in">print</span>(outer_b.inner)
<span class="hljs-built_in">print</span>(outer_b.inner <span class="hljs-keyword">is</span> outer_a.inner)
</code></pre></div>
<p>La façon idiomatique est d’utiliser <code>None</code> comme valeur par défaut et documenter le comportement :</p>
<div class="hljs-code-div hljs-code-python"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span></div><pre><code class="hljs language-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Outer</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, inner=<span class="hljs-literal">None</span></span>):</span>
self.inner = inner <span class="hljs-keyword">if</span> inner <span class="hljs-keyword">is</span> <span class="hljs-keyword">not</span> <span class="hljs-literal">None</span> <span class="hljs-keyword">else</span> []
</code></pre></div>noms, PyObjects, et identification, message #2378952021-10-01T11:30:08+02:00buffalo974/@buffalo974https://zestedesavoir.com/forums/sujet/15734/noms-pyobjects-et-identification/?page=1#p237895<p>parfait ! merci !</p>noms, PyObjects, et identification, message #2378792021-10-01T00:32:53+02:00adri1/@adri1https://zestedesavoir.com/forums/sujet/15734/noms-pyobjects-et-identification/?page=1#p237879<blockquote>
<p>Le C, j’aime pas trop … je trouve ça "vieux". Le rust est super mais à un moment je m’étais embrouillé avec les lifetime, Box, Rc, Refcell etc.</p>
</blockquote>
<p>Si tu veux te frotter au bas niveau et la programmation système, il est indéniablement utile de pouvoir <em>au moins lire</em> du C en raison de son ubiquité. Il n’est pas question d’écrire des codes sérieux avec, simplement de connaitre le langage dans les grandes lignes. Ça peut avoir des avantages en apprenant Rust, d’ailleurs : en comprenant mieux la montagne de problèmes associés avec les pointeurs nus (et la gestion d’erreur très fragile) en C, tu vas voir d’un autre œil les abstractions offertes par Rust et ce qu’elles apportent. Tu pourrais de fait y voir un peu plus clair et être embrouillé moins facilement.</p>
<p>Pour ton autre problème, considère le code suivant :</p>
<div class="hljs-code-div hljs-code-python"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span><span data-count="5"></span><span data-count="6"></span><span data-count="7"></span><span data-count="8"></span><span data-count="9"></span><span data-count="10"></span><span data-count="11"></span><span data-count="12"></span><span data-count="13"></span><span data-count="14"></span></div><pre><code class="hljs language-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Inner</span>:</span>
<span class="hljs-keyword">pass</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Outer</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
self.inner = Inner()
<span class="hljs-built_in">print</span>(<span class="hljs-built_in">locals</span>())
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
outer = Outer()
<span class="hljs-built_in">print</span>(outer.__dict__)
<span class="hljs-built_in">print</span>(<span class="hljs-built_in">dir</span>(outer))
</code></pre></div>
<p>L’exécuter donne une sortie du genre :</p>
<div class="hljs-code-div hljs-code-python"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span></div><pre><code class="hljs language-python">{<span class="hljs-string">'self'</span>: <__main__.Outer <span class="hljs-built_in">object</span> at <span class="hljs-number">0x7fd6e327d3a0</span>>}
{<span class="hljs-string">'inner'</span>: <__main__.Inner <span class="hljs-built_in">object</span> at <span class="hljs-number">0x7fd6e327d310</span>>}
[<span class="hljs-string">'__class__'</span>, <span class="hljs-string">'__delattr__'</span>, <span class="hljs-string">'__dict__'</span>, <span class="hljs-string">'__dir__'</span>, <span class="hljs-string">'__doc__'</span>, <span class="hljs-string">'__eq__'</span>, <span class="hljs-string">'__format__'</span>, <span class="hljs-string">'__ge__'</span>, <span class="hljs-string">'__getattribute__'</span>, <span class="hljs-string">'__gt__'</span>, <span class="hljs-string">'__hash__'</span>, <span class="hljs-string">'__init__'</span>, <span class="hljs-string">'__init_subclass__'</span>, <span class="hljs-string">'__le__'</span>, <span class="hljs-string">'__lt__'</span>, <span class="hljs-string">'__module__'</span>, <span class="hljs-string">'__ne__'</span>, <span class="hljs-string">'__new__'</span>, <span class="hljs-string">'__reduce__'</span>, <span class="hljs-string">'__reduce_ex__'</span>, <span class="hljs-string">'__repr__'</span>, <span class="hljs-string">'__setattr__'</span>, <span class="hljs-string">'__sizeof__'</span>, <span class="hljs-string">'__str__'</span>, <span class="hljs-string">'__subclasshook__'</span>, <span class="hljs-string">'__weakref__'</span>, <span class="hljs-string">'inner'</span>]
</code></pre></div>
<p><code>locals</code> ne voit que les variables (les "noms" pour reprendre la nomenclature de ton tuto) définies localement. <code>globals</code> est la même chose mais au niveau du module au lieu du scope local. Les membres d’un objet sont situés dans son attribut <code>__dict__</code>. <code>dir</code> vise un peu plus large et sort aussi les attributs spéciaux (dont la gestion est internée par Python).</p>
<p>Note que le fait que la méthode <code>__getattr__</code> (et <code>__getattribute__</code>) peuvent exécuter du code arbitraire et le mécanisme des descripteurs fait que l’interface effective d’un objet est plus large que ce que <code>dir</code> renvoie.</p>noms, PyObjects, et identification, message #2378782021-09-30T22:06:45+02:00buffalo974/@buffalo974https://zestedesavoir.com/forums/sujet/15734/noms-pyobjects-et-identification/?page=1#p237878<p>Oui tu as raison, maintenant je me rappelle d’avoir croisé PyO3 ça va être interessant.
Le C, j’aime pas trop … je trouve ça "vieux".
Le rust est super mais à un moment je m’étais embrouillé avec les lifetime, Box, Rc, Refcell etc.
dernière question pour refermer ce topique, je n’arrive pas à rendre visible dans inspect.locals et inspect.globals des objets contenus dans d’autres objets.
Quelles sont les adresses des objets extra et inner à l' interieur de outer ?
Et si je met en attribut de outer une liste d' objets, ou un dictionnaire contenant des objets ?</p>
<div class="hljs-code-div hljs-code-py"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span><span data-count="5"></span><span data-count="6"></span><span data-count="7"></span><span data-count="8"></span><span data-count="9"></span><span data-count="10"></span><span data-count="11"></span><span data-count="12"></span><span data-count="13"></span><span data-count="14"></span><span data-count="15"></span><span data-count="16"></span><span data-count="17"></span><span data-count="18"></span><span data-count="19"></span><span data-count="20"></span><span data-count="21"></span><span data-count="22"></span><span data-count="23"></span><span data-count="24"></span><span data-count="25"></span><span data-count="26"></span><span data-count="27"></span><span data-count="28"></span><span data-count="29"></span><span data-count="30"></span><span data-count="31"></span><span data-count="32"></span><span data-count="33"></span><span data-count="34"></span><span data-count="35"></span><span data-count="36"></span><span data-count="37"></span><span data-count="38"></span><span data-count="39"></span><span data-count="40"></span><span data-count="41"></span><span data-count="42"></span><span data-count="43"></span><span data-count="44"></span><span data-count="45"></span><span data-count="46"></span><span data-count="47"></span><span data-count="48"></span><span data-count="49"></span><span data-count="50"></span><span data-count="51"></span><span data-count="52"></span><span data-count="53"></span><span data-count="54"></span><span data-count="55"></span><span data-count="56"></span><span data-count="57"></span><span data-count="58"></span><span data-count="59"></span><span data-count="60"></span><span data-count="61"></span><span data-count="62"></span><span data-count="63"></span><span data-count="64"></span><span data-count="65"></span><span data-count="66"></span><span data-count="67"></span><span data-count="68"></span><span data-count="69"></span><span data-count="70"></span><span data-count="71"></span><span data-count="72"></span><span data-count="73"></span><span data-count="74"></span><span data-count="75"></span><span data-count="76"></span><span data-count="77"></span><span data-count="78"></span><span data-count="79"></span><span data-count="80"></span><span data-count="81"></span><span data-count="82"></span><span data-count="83"></span><span data-count="84"></span><span data-count="85"></span><span data-count="86"></span><span data-count="87"></span><span data-count="88"></span><span data-count="89"></span><span data-count="90"></span></div><pre><code class="hljs language-py"><span class="hljs-keyword">import</span> gc
<span class="hljs-string">"""
bigmachinery = gc.get_objects()
for machine in bigmachinery:
print(f"- {machine} type {type(machine)} ")
print(len(bigmachinery))
"""</span>
<span class="hljs-keyword">import</span> os
<span class="hljs-keyword">import</span> sys
<span class="hljs-keyword">import</span> inspect
<span class="hljs-keyword">from</span> collections <span class="hljs-keyword">import</span> *
<span class="hljs-keyword">import</span> collections
<span class="hljs-keyword">import</span> ctypes
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Inner</span>():</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
self.secret = <span class="hljs-string">"this is inner secret"</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Extra</span>():</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, extramsg</span>):</span>
self.extramsg = extramsg
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Outer</span>():</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, msg: <span class="hljs-built_in">str</span>, nested_obj = Inner(<span class="hljs-params"></span>)</span>):</span>
self.msg = msg
self.nested_obj = nested_obj
self.extra_obj = <span class="hljs-literal">None</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">setup</span>(<span class="hljs-params">self</span>):</span>
self.<span class="hljs-built_in">locals</span> = <span class="hljs-built_in">locals</span>()
self.gobals = <span class="hljs-built_in">globals</span>()
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">make_extra</span>(<span class="hljs-params">self</span>):</span>
x = <span class="hljs-built_in">input</span>(<span class="hljs-string">"please give a short message : "</span>)
self.extra_obj = Extra(x)
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">show_loc_and_glob</span>(<span class="hljs-params">self</span>):</span>
<span class="hljs-built_in">print</span>(<span class="hljs-string">"\n *******"</span>)
<span class="hljs-built_in">print</span>(self.<span class="hljs-built_in">locals</span>)
<span class="hljs-built_in">print</span>(<span class="hljs-string">"---------"</span>)
<span class="hljs-keyword">for</span> glob <span class="hljs-keyword">in</span> self.gobals:
<span class="hljs-built_in">print</span>(glob)
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">main</span>():</span>
<span class="hljs-built_in">print</span>(<span class="hljs-string">"inside main fn"</span>)
my_out = Outer(<span class="hljs-string">"out message"</span>)
<span class="hljs-built_in">print</span>(<span class="hljs-string">" my_out = "</span>, my_out)
my_out.setup()
my_out.show_loc_and_glob()
my_out.make_extra()
my_out.show_loc_and_glob()
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:
main()
</code></pre></div>noms, PyObjects, et identification, message #2378632021-09-30T14:44:21+02:00adri1/@adri1https://zestedesavoir.com/forums/sujet/15734/noms-pyobjects-et-identification/?page=1#p237863<blockquote>
<p>penses qu’il serait possible avec l' interpréteur rustpython d’utiliser un équivalent de ctypes.CDLL(mon_executable_ecris_en_rust) pour importé un faux objet python, sculté de A à Z côté rust ? Il ne s’agit pas de deserialization mais de "tricotage" d' objet d’un langage vers un autre. Un peu comme on forgerait manuellement des paquet avec scapy ? C’est expérimental pour découvrir par l’erreur…</p>
</blockquote>
<p>Je pense que tu ne prends pas le problème du bon angle. La bonne façon de faire ça est d’utiliser directement <a href="https://docs.python.org/3/extending/extending.html">l’API C de Python</a>, qui fonctionne dans les deux sens. Tu as <a href="https://github.com/PyO3/pyo3">PyO3 en Rust</a> qui est un binding de cet API. Techniquement, en arrière plan, ça fait tout ce "tricotage" dont tu parles.</p>
<blockquote>
<p>je vais jetter un coup d' oeil à cython et aux pointeurs avant de descendre plus bas</p>
</blockquote>
<p>Tu pars un peu dans tous les sens là, cython est un langage plus large que Python, que tu peux utiliser pour interface C et Python. C’est encore une approche un peu différente. Pas sur de ce que tu veux dire par "jeter un œil aux pointeurs", si tu ne sais pas ce qu’est un pointeur maintenant, c’est effectivement un bon moment pour apprendre (mais normalement, tu as croisé ça en apprenant Rust). Une façon de faire pourrait être de lire le tuto sur le C qu’on a ici, t’as vite fait le tour de C et ça te rafraîchira la mémoire sur des notions bas niveau.</p>noms, PyObjects, et identification, message #2378492021-09-29T20:32:34+02:00buffalo974/@buffalo974https://zestedesavoir.com/forums/sujet/15734/noms-pyobjects-et-identification/?page=1#p237849<p><a href="/@adri1" rel="nofollow" class="ping ping-link">@<span class="ping-username">adri1</span></a> : penses qu’il serait possible avec l' interpréteur rustpython d’utiliser un équivalent de
ctypes.CDLL(mon_executable_ecris_en_rust) pour importé un faux objet python, sculté de A à Z côté rust ?
Il ne s’agit pas de deserialization mais de "tricotage" d' objet d’un langage vers un autre.
Un peu comme on forgerait manuellement des paquet avec scapy ?
C’est expérimental pour découvrir par l’erreur…</p>
<p>par exemple:</p>
<div class="hljs-code-div hljs-code-py"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span></div><pre><code class="hljs language-py"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Foobar</span>():</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self,dico,listo</span>):</span>
self.mydict = dico
self.mylist = listo
</code></pre></div>
<p>et d’exporter une instance baz de Foobar de rust vers python ?</p>
<p>EDIT : ça à l’air d’être une usine à gaz, je vais jetter un coup d' oeil à cython et aux pointeurs avant de descendre plus bas.</p>noms, PyObjects, et identification, message #2378412021-09-29T14:58:09+02:00adri1/@adri1https://zestedesavoir.com/forums/sujet/15734/noms-pyobjects-et-identification/?page=1#p237841<blockquote>
<p><a href="/@adri1" rel="nofollow" class="ping ping-link">@<span class="ping-username">adri1</span></a> : dans le mille c’est le cas de le dire. Merci pour la précision sur
objets Python = Rc<RefCell<T>>
si tu as d' autres points de comparaisons sur Rust ou en Asm ça m' interesse énormément.</p>
</blockquote>
<p>Il n’y a pas forcément grand chose d’intéressant à dire sur le modèle mémoire de Python. Cela dit, le fait que les objets sont en gros des <code>Rc<RefCell<T>></code> plutôt que des <code>Arc<Mutex<T>></code> explique la nécessité du GIL: leur design est trop fragile pour garantir que leur manipulation est <em>thread safe</em>. Un autre parallèle, beaucoup plus immédiat, est que les dictionnaires en Python (qui sont présents partout) sont en gros des <code>HashMap<K, V></code> et demandent que les <code>K</code> soient hashables (ce qui rejoint l’erreur que tu as mentionnée plus bas).</p>
<blockquote>
<p>As tu des conseils de dissection pour aller grater là où c’est le
plus interessant ? j’ai remarqué locals, globals, gc, inspect, ctypes peut-être stuct.</p>
</blockquote>
<p>T’as des trucs assez variés qui touchent à des choses assez différentes. <code>gc</code> est probablement le plus proche de ce que tu as déjà abordé dans ce sujet, il donne accès au garbage collector. Il s’occupe de nettoyer les objets dont le compteur de référence est tombé à 0, et surtout a des heuristiques pour détecter les cycles de références qui ne sont pas joignables de l’extérieur. La comparaison avec <code>Rc</code> s’effrite ici d’ailleurs, puisque le modèle d'<em>ownership</em> de Rust couplé à <code>Rc</code> ne permet pas d’éliminer un cycle de <code>Rc</code> (d’où la nécessité de <code>Weak<T></code>). Le fait que Python utilise un GC (plutôt que bêtement virer les objets dès que leur nombre de référence tombe à 0 comme le fait <code>Rc</code>) est uniquement pour éviter les fuites lorsqu’il y a un cycle de référence.</p>
<p><code>locals</code>, <code>globals</code> et <code>inspect</code> te permettent de jouer avec les mécanismes du langage plutôt que de son implémentation, pas sur que ce soit ce que tu cherches.</p>
<p><code>ctypes</code> et <code>struct</code> seront utiles pour t’interface avec du code C (ou qui respecte l’API C), tu pourrais avoir intérêt à fouiller du côté de <a href="https://docs.python.org/3/c-api/index.html">l’API C offerte par Python</a>.</p>
<p>Un truc qui me parait plus dans la ligné directe de ce que tu veux faire est <a href="https://docs.python.org/3/library/dis.html">le module <code>dis</code></a> qui te permet de manipuler le bytecode interprété par la machine virtuelle CPython (l’implémentation standard de Python). Le code Python est compilé sous forme de bytecode (et mis dans le dossier <code>__pycache__</code> que tu as sûrement vu trainer). C’est ce bytecode qui est interprété plutôt que le code Python lui-même (pour des raisons de perf).</p>
<blockquote>
<p>Je vais essayer de recréer un dict customisé, j’ai eu des erreurs du genre
TypeError: unhashable type: 'dict’. Un article de blog qui va en profondeur sur ce genre d' experimentations ?</p>
</blockquote>
<p>Pas facile de donner plus de détails sans un code, mais ton problème est que les clés des dictionnaires doivent implémenter <code>__hash__</code> (pour pouvoir construire la hash table qui permet le lookup en temps amorti constant), autrement dit être hashable. De manière similaire, pour <code>HashMap<K, V></code>, tu as besoin de <code>K: Hash</code> (et <code>Eq</code> mais c’est un choix de Rust).</p>
<p>Or, les instances de dictionnaires ne sont pas hashable. Le message d’erreur est pas terrible d’ailleurs, parce que le <em>type</em> <code>dict</code> (qui est une instance de <code>type</code>) lui est parfaitement hashable. De manière générale, les mutables ne sont pas hashable en Python (tes propres types peuvent l’être si tu veux par contre), je pense pour éviter de casser l’attente <code>id(a) == id(b)</code> implique <code>hash(a) == hash(b)</code> (avec des valeurs mutables, ça va dépendre de ce qui se passe entre les deux calculs de hash comme on s’attend à ce que le hash dépende de la valeur).</p>noms, PyObjects, et identification, message #2378342021-09-28T20:19:32+02:00entwanne/@entwannehttps://zestedesavoir.com/forums/sujet/15734/noms-pyobjects-et-identification/?page=1#p237834<figure><blockquote>
<p><a href="/@entwanne" rel="nofollow" class="ping ping-link">@<span class="ping-username">entwanne</span></a> : objets internés, c’est du nested objects ?</p>
</blockquote><figcaption><a href="https://zestedesavoir.com/forums/sujet/15734/noms-pyobjects-et-identification/?page=1#p237832">buffalo974</a></figcaption></figure>
<p>Non c’est le mécanisme qui fait que des instances de certains objets sont conservées dans la mémoire interne de l’interpréteur pour être renvoyées quand tu demandes à nouveau une valeur similaire.</p>
<p>C’est accessible via la fonction <code>intern</code> du module <code>sys</code> (c’était auparavant une fonction <em>built-in</em> en Python 2) qui te permet d'<em>interner</em> des chaînes de caractères.</p>
<p>Sans <code>intern</code> :</p>
<div class="hljs-code-div hljs-code-python"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span></div><pre><code class="hljs language-python"><span class="hljs-meta">>>> </span>s2 = <span class="hljs-string">'a'</span> * <span class="hljs-number">1000</span>
<span class="hljs-meta">>>> </span>s2 = <span class="hljs-string">'a'</span> * <span class="hljs-number">1000</span>
<span class="hljs-meta">>>> </span>s1 <span class="hljs-keyword">is</span> s2
<span class="hljs-literal">False</span>
</code></pre></div>
<p>Avec <code>intern</code> :</p>
<div class="hljs-code-div hljs-code-python"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span><span data-count="5"></span><span data-count="6"></span><span data-count="7"></span></div><pre><code class="hljs language-python"><span class="hljs-meta">>>> </span><span class="hljs-keyword">import</span> sys
<span class="hljs-meta">>>> </span>sys.intern(<span class="hljs-string">'a'</span> * <span class="hljs-number">1000</span>)
<span class="hljs-string">'aaa...'</span>
<span class="hljs-meta">>>> </span>s1 = <span class="hljs-string">'a'</span> * <span class="hljs-number">1000</span>
<span class="hljs-meta">>>> </span>s2 = <span class="hljs-string">'a'</span> * <span class="hljs-number">1000</span>
<span class="hljs-meta">>>> </span>s1 <span class="hljs-keyword">is</span> s2
<span class="hljs-literal">True</span>
</code></pre></div>noms, PyObjects, et identification, message #2378322021-09-28T18:53:27+02:00buffalo974/@buffalo974https://zestedesavoir.com/forums/sujet/15734/noms-pyobjects-et-identification/?page=1#p237832<p><a href="/@entwanne" rel="nofollow" class="ping ping-link">@<span class="ping-username">entwanne</span></a> : objets internés, c’est du nested objects ?</p>
<p><a href="/@deuchnord" rel="nofollow" class="ping ping-link">@<span class="ping-username">deuchnord</span></a> : bonne remarque</p>
<p><a href="/@adri1" rel="nofollow" class="ping ping-link">@<span class="ping-username">adri1</span></a> : dans le mille c’est le cas de le dire. Merci pour la précision sur
objets Python = Rc<RefCell<T>>
si tu as d' autres points de comparaisons sur Rust ou en Asm ça m' interesse énormément. As tu des conseils de dissection pour aller grater là où c’est le
plus interessant ? j’ai remarqué locals, globals, gc, inspect, ctypes peut-être stuct. Je vais essayer de recréer un dict customisé, j’ai eu des erreurs du genre
TypeError: unhashable type: 'dict’. Un article de blog qui va en profondeur sur ce genre d' experimentations ?
J’ai pensé aussi a exploré depuis un autre processus mais là c’est chaud. </p>
<p><a href="/@Geo" rel="nofollow" class="ping ping-link">@<span class="ping-username">Geo</span></a> si tu passes dans le coin, tes lumières sont les bienvenues. Avec bitstring, volatility et capstone il doit il y avoir des super trucs à faire. Je ne sais pas si volatility ne fonctionne que sur de la RAM figée ou si on peut faire un seul processus et en live.</p>noms, PyObjects, et identification, message #2378312021-09-28T15:26:04+02:00adri1/@adri1https://zestedesavoir.com/forums/sujet/15734/noms-pyobjects-et-identification/?page=1#p237831<p>Salut,</p>
<p>L’exemple du tuto n’est effectivement pas ultra-clair, il n’y a aucune garantie que <code>x</code> et <code>y</code> vont pointer vers le même objet en mémoire. C’est montré de façon un peu détourner avec l’exemple suivant qui créé 1000 de façon détournée avec une somme <code>501+499</code> qui se retrouve à une adresse différente du premier <code>1000</code>. Note que tout ça est fortement dépendent de la version que tu utilises, il n’y a aucune garantie que les exemples de ce tuto vont continuer à fonctionner dans le futur. Peut être qu’un jour, 1000 sera parmi les objets internés au lieu d’être dupliqué.</p>
<p>Par ailleurs, je rebondi un peu sur ce point :</p>
<blockquote>
<p>je fais de l’introspection sur python avant de repartir sur des langages plus bas niveau</p>
</blockquote>
<p>Si ton but est de disséquer un peu le fonctionnement interne de Python, très bien, c’est intéressant en soi. Si ton but est de t’en servir comme tremplin vers le bas niveau, c’est probablement une mauvaise idée : tu vas surtout te familiariser avec les bizarreries de la machine virtuelle Python et toutes les astuces qui sont là pour améliorer un peu les performances en jouant autour du modèle mémoire. Au final, ce sera très particulier et bourré de pratiques qui ne sont absolument pas nécessaires lorsqu’on fait de la programmation système.</p>
<p>Essentiellement, les objets Python sont des <code>Rc<RefCell<T>></code> (toi qui a touché un peu à Rust si je ne m’abuse) : des pointeurs vers des objets sur le <em>heap</em> dont l’état interne est mutable. Le reste sont des fioritures pour savoir quand on créé un nouvel objet plutôt que modifier l’existant (mutables vs immutables) et comment on évite (un peu) la duplication d’objets (avec le mécanisme d’objets internés).</p>noms, PyObjects, et identification, message #2378272021-09-28T13:09:29+02:00Deuchnord/@Deuchnordhttps://zestedesavoir.com/forums/sujet/15734/noms-pyobjects-et-identification/?page=1#p237827<p>Il est possible d’ailleurs que le tutoriel contienne une erreur, et qu’il faille plutôt lire ceci :</p>
<div class="hljs-code-div hljs-code-python"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span></div><pre><code class="hljs language-python"><span class="hljs-meta">>>> </span>x = <span class="hljs-number">1000</span>
<span class="hljs-meta">>>> </span>y = x
<span class="hljs-meta">>>> </span>x <span class="hljs-keyword">is</span> y
<span class="hljs-literal">True</span>
</code></pre></div>
<p>Ce qui me semble d’ailleurs plus logique.</p>noms, PyObjects, et identification, message #2378262021-09-28T13:05:42+02:00entwanne/@entwannehttps://zestedesavoir.com/forums/sujet/15734/noms-pyobjects-et-identification/?page=1#p237826<p>Salut,</p>
<p>C’est bien là tout le soucis de l’opérateur <code>is</code> utilisé sur des nombres et ce qui est expliqué dans le cours.</p>
<p>Ce sont des optimisations qui font que les nombres vont être internés et donc que la même instance sera renvoyée. On ne peut donc pas se reposer là-dessus pour avoir un comportement fiable.</p>noms, PyObjects, et identification, message #2378252021-09-28T12:49:35+02:00buffalo974/@buffalo974https://zestedesavoir.com/forums/sujet/15734/noms-pyobjects-et-identification/?page=1#p237825<p>Salut,
je fais de l’introspection sur python avant de repartir sur des langages plus bas niveau.
voici un bon tuto:
<a href="https://realpython.com/pointers-in-python/">https://realpython.com/pointers-in-python/</a></p>
<p>au moment d’avoir le sourire de quelqu’un qui commence à comprendre, je teste en ligne de commande puis avec idle3. Et ça plante…</p>
<p>le tuto dit celà:</p>
<div class="hljs-code-div hljs-code-py"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span></div><pre><code class="hljs language-py"><span class="hljs-meta">>>> </span>x = <span class="hljs-number">1000</span>
<span class="hljs-meta">>>> </span>y = <span class="hljs-number">1000</span>
<span class="hljs-meta">>>> </span>x <span class="hljs-keyword">is</span> y
<span class="hljs-literal">True</span>
</code></pre></div>
<p>ce qui aurait bien collé avec leurs explications.</p>
<p>Chez moi:</p>
<div class="hljs-code-div hljs-code-py"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span><span data-count="5"></span><span data-count="6"></span><span data-count="7"></span><span data-count="8"></span></div><pre><code class="hljs language-py"><span class="hljs-meta">>>> </span>x = <span class="hljs-number">1000</span>
<span class="hljs-meta">>>> </span>y = <span class="hljs-number">1000</span>
<span class="hljs-meta">>>> </span>x <span class="hljs-keyword">is</span> y
<span class="hljs-literal">False</span>
<span class="hljs-meta">>>> </span><span class="hljs-built_in">id</span>(x)
<span class="hljs-number">140191909473360</span>
<span class="hljs-meta">>>> </span><span class="hljs-built_in">id</span>(y)
<span class="hljs-number">140191909473424</span>
</code></pre></div>
<p>du coup je ne sais pas quelle partie de leur tuto est correcte (moi qui avais "compris" ;-( )
???</p>Besoin d'aide pour mon mémoire, message #2330552021-04-06T22:30:45+02:00qwerty/@qwertyhttps://zestedesavoir.com/forums/sujet/15224/besoin-daide-pour-mon-memoire/?page=1#p233055<p>Chic ! Hâte de lire, ça m’intéresserait d’en savoir plus :-)</p>Besoin d'aide pour mon mémoire, message #2330542021-04-06T22:28:20+02:00Ju/@Juhttps://zestedesavoir.com/forums/sujet/15224/besoin-daide-pour-mon-memoire/?page=1#p233054<p><a href="/membres/voir/qwerty/" rel="nofollow" class="ping ping-link">@<span class="ping-username">qwerty</span></a> oui avec plaisir! Il sera rédigé vers fin mai / début juin, avec analyse des résultats et discussion pour que ce soit un peu plus pertinent que juste les résultats</p>Besoin d'aide pour mon mémoire, message #2330532021-04-06T21:54:23+02:00qwerty/@qwertyhttps://zestedesavoir.com/forums/sujet/15224/besoin-daide-pour-mon-memoire/?page=1#p233053<p>Salut !</p>
<p>On a eu de nombreux cas où il y a eu des questionnaires, sans retour derrière. Là, ça semble être adossé à un mémoire de master, serait-il possible d’avoir, une fois le mémoire rédigée bien sûr, un retour sur les résultats ?</p>
<p>Zestement,</p>Besoin d'aide pour mon mémoire, message #2330512021-04-06T20:17:49+02:00Ju/@Juhttps://zestedesavoir.com/forums/sujet/15224/besoin-daide-pour-mon-memoire/?page=1#p233051<p>Bonjour à toutes et tous !</p>
<p>J’espère que vous allez bien ! J’ai besoin de votre aide pour mon mémoire de fin d’année pour lequel je dois récolter un maximum de participations. Mon mémoire porte sur la formation d’impressions et la prise de décisions, et se présente sous la forme d’un tout petit questionnaire (il est dit 10min mais en général les gens mettent 4–5 min grand max), et les réponses sont totalement anonymes.
Voici le lien du questionnaire : <a href="https://ufrpsycho.eu.qualtrics.com/jfe/form/SV_72nM2EEnzzvGq8K">https://ufrpsycho.eu.qualtrics.com/jfe/form/SV_72nM2EEnzzvGq8K</a></p>
<p>Votre participation m’est d’une GRANDE aide, je vous remercie d’avance !!
Bonne journée ou soirée !!</p>Comment vis-tu dans ton lit ?, message #2326252021-03-25T17:11:50+01:00Herbe/@Herbehttps://zestedesavoir.com/forums/sujet/15131/comment-vis-tu-dans-ton-lit/?page=1#p232625<p>Oh zut j’ai raté ce questionnaire qui m’avait l’air fort croustillant. <img src="/static/smileys/svg/pleure.svg" alt=":'(" class="smiley"> </p>[Rust] String standard qui ne veut pas se réallouer au delà de 1 ko, message #2323882021-03-17T11:33:57+01:00Renault/@Renaulthttps://zestedesavoir.com/forums/sujet/15154/rust-string-standard-qui-ne-veut-pas-se-reallouer-au-dela-de-1-ko/?page=1#p232388<p>Oui je vois, ramené à cet exemple c’est évident.</p>
<p>Merci beaucoup. <img src="/static/smileys/svg/smile.svg" alt=":)" class="smiley"></p>[Rust] String standard qui ne veut pas se réallouer au delà de 1 ko, message #2323832021-03-17T10:02:00+01:00adri1/@adri1https://zestedesavoir.com/forums/sujet/15154/rust-string-standard-qui-ne-veut-pas-se-reallouer-au-dela-de-1-ko/?page=1#p232383<p>Ce code est invalide :</p>
<div class="hljs-code-div hljs-code-rust"><div class="hljs-line-numbers"><span data-count="1"></span><span data-count="2"></span><span data-count="3"></span><span data-count="4"></span><span data-count="5"></span><span data-count="6"></span><span data-count="7"></span><span data-count="8"></span><span data-count="9"></span></div><pre><code class="hljs language-rust"><span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">rptr</span></span>() -> *<span class="hljs-keyword">const</span> <span class="hljs-built_in">i32</span> {
<span class="hljs-keyword">let</span> v = <span class="hljs-number">42</span>;
&v
}
<span class="hljs-function"><span class="hljs-keyword">fn</span> <span class="hljs-title">main</span></span>() {
<span class="hljs-keyword">let</span> ptr = rptr();
<span class="hljs-built_in">println!</span>(<span class="hljs-string">"{}"</span>, <span class="hljs-keyword">unsafe</span>{*ptr});
}
</code></pre></div>
<p>En <code>debug</code> il semble fonctionner, mais en <code>release</code> il imprime simplement <code>0</code> (du moins sur ma machine). La valeur 42 n’est plus valide en dehors de <code>rptr</code> même il reste un pointeur nu dessus. Si tu essaies de renvoyer un <code>&i32</code>, le compilateur te demande une <em>lifetime</em>. Si tu en mets une, le <em>borrow checker</em> va gentiment te signaler que tu renvoies une référence à des données qui sont possédées par la fonction <code>rptr</code>.</p>[Rust] String standard qui ne veut pas se réallouer au delà de 1 ko, message #2323792021-03-17T09:18:10+01:00Renault/@Renaulthttps://zestedesavoir.com/forums/sujet/15154/rust-string-standard-qui-ne-veut-pas-se-reallouer-au-dela-de-1-ko/?page=1#p232379<blockquote>
<p>Le pointeur oui, mais qui possède les données pointées ? Rust ne garantie pas que les données derrière un pointeur nu restent valides.</p>
</blockquote>
<p>Je pensais, du moins si ce dernier n’était ni modifié (ce qui était mon cas), ni détruit volontairement (idem).</p>
<blockquote>
<p> Là, tu n’as aucun code qui vérifie cet invariant, une fonction safe qui contient juste un bloc unsafe mais rien qui vérifie les invariants de ce bloc n’a aucune garantie de fonctionner. </p>
</blockquote>
<p>Comme le pointeur a été valide et qu’il n’a pas été altéré selon moi, c’était bon. Mais manifestement je me suis trompé. Je dois approfondir ce point dans ma compréhension de Rust.</p>
<p>Il est clair que j’ai eu un mauvais réflexe ici.</p>
<blockquote>
<p>(Par ailleurs, de manière générale, si tu te trimbales un pointeur nu en Rust alors que tu n’es pas en train d’écrire un pointeur intelligent, c’est probablement une erreur de design).</p>
</blockquote>
<p>Ce bout de code a quelques mois maintenant, je m’y suis remis très récemment et il est vrai que je n’avais pas vu les pointeur intelligents à ce stade en Rust. Merci du conseil ! <img src="/static/smileys/svg/smile.svg" alt=":)" class="smiley"></p>