i have taught quite a few people of various backgrounds and levels. And still provide a short crash-course, once in a while.<p>IMO in this article the elephant is missing, esp. for C/C++/java people: there are no variables as storage-spaces in Python. There are names/labels in namespaces, attached/referencing some value (stored in VM), and that is taken/examined at runtime-usage of those labels/names. The values themselves are living on other side of the fence, inside the virtual machine.<p>The most important piece of the language Python in docs is the execution model, and in it, the "naming and binding" part:<p><a href="https://docs.python.org/3.11/reference/executionmodel.html#naming-and-binding" rel="nofollow">https://docs.python.org/3.11/reference/executionmodel.html#n...</a><p>i.e. what constitutes a namespace, how are they stacked at declare-time or run-time (visibility/shadowing), lifetimes, scopes and all that.<p>The most usual gotcha is that inside of class xyz: ... is only a temporary namespace - and becomes class' attributes when closed (well, subject to metaclass behaviour).<p>i usually present the "storage" as "imagine 2 notebooks of ~transparent-sheets" : one is the names' visibility (so called "variables") - namespace-hierarchy, where each sheet is one namespace level, and you see only the inner-most page that has something in certain row - shadowing all those towards the root at module level; the other is the attribute-on-something visibility, where the instance (if any, of whatever type) is (only one and) always on top, and then inherited <i>classes</i> (not instances) underneath one under another. Also, all instance-or-static methods in Python are virtual, i.e. using the topmost available - while class-methods are not, they use the specified-or-below but not above.<p>Frankly, took me ~10 years, occasionally rereading that chapter each time when hitting new category of errors, to grasp the whole of it. <i>Each comma there matters</i>. Take your time.<p>Edit: this "names-only" thing is similar in javascript, and other interpreted languages. Python also exposes the whole VM-runtime - from programmer's side of the fence - i.e. locals() is the current namespace, inspect.stack() gives the current namespace hierarchy, etc. Self-reflection can be taken quite far