From e567c45e18d66cd4de96820d261f82afe487dcad Mon Sep 17 00:00:00 2001
From: Silvio Rhatto <rhatto@riseup.net>
Date: Wed, 15 May 2019 12:45:07 -0300
Subject: [PATCH] Research: Python: scopes, namespaces and memory references

---
 research/python.md | 65 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/research/python.md b/research/python.md
index 71f27ef..98e007f 100644
--- a/research/python.md
+++ b/research/python.md
@@ -75,8 +75,10 @@ Python encourages polymorphism:
 
     Numbers (integer, floating-point, decimal, fraction, others)
     Support addition, multiplication, etc.
+
     Sequences (strings, lists, tuples)
     Support indexing, slicing, concatenation, etc.
+
     Mappings (dictionaries)
     Support indexing by key, etc.
 
@@ -101,6 +103,69 @@ Also, [take care with handling mutables as arguments and as default arguments](h
 also explained [here](https://docs.python.org/3/tutorial/controlflow.html#default-argument-values) and [here](https://docs.python-guide.org/writing/gotchas/)
 (common gotchas).
 
+From [Scopes an Namespaces](https://docs.python.org/3/tutorial/classes.html#python-scopes-and-namespaces), telling that assignments bind names to objects:
+
+    A special quirk of Python is that – if no global statement is in effect –
+    assignments to names always go into the innermost scope. Assignments do not
+    copy data — they just bind names to objects. The same is true for deletions:
+    the statement del x removes the binding of x from the namespace referenced by
+    the local scope. In fact, all operations that introduce new names use the local
+    scope: in particular, import statements and function definitions bind the
+    module or function name in the local scope.
+
+    The global statement can be used to indicate that particular variables live in
+    the global scope and should be rebound there; the nonlocal statement indicates
+    that particular variables live in an enclosing scope and should be rebound
+    there.
+
+    [...]
+
+    Actually, you may have guessed the answer: the special thing about methods is
+    that the instance object is passed as the first argument of the function. In
+    our example, the call x.f() is exactly equivalent to MyClass.f(x). In general,
+    calling a method with a list of n arguments is equivalent to calling the
+    corresponding function with an argument list that is created by inserting the
+    method’s instance object before the first argument.
+
+Week references (from [here](https://docs.python.org/3/tutorial/stdlib2.html):
+
+    Python does automatic memory management (reference counting for most objects
+    and garbage collection to eliminate cycles). The memory is freed shortly after
+    the last reference to it has been eliminated.
+
+Now explain this:
+
+    Python 2.7.13 (default, Sep 26 2018, 18:42:22)
+    [GCC 6.3.0 20170516] on linux2
+    Type "help", "copyright", "credits" or "license" for more information.
+    >>> hex(id([]))
+    '0x7f6264bbf368'
+    >>> hex(id([]))
+    '0x7f6264bbf368'
+    >>> x = []
+    >>> hex(id(x))
+    '0x7f6264bbf368'     # both x and [] points to the same memory location
+    >>> x.append('0')
+    >>> hex(id(x))
+    '0x7f6264bbf368'     # x still points to the same memory location
+    >>> hex(id([]))
+    '0x7f6264baeab8'     # now [] points somewhere else
+    >>> hex(id('test'))
+    '0x7f6264bc9480'
+    >>> x = 'test'
+    >>> hex(id(x))
+    '0x7f6264bc9450'
+    >>> hex(id('test'))
+    '0x7f6264bc9450'
+    >>> hex(id('another test'))
+    '0x7f6264bcc1f0'
+    >>> x = 'another test'
+    >>> hex(id(x))
+    '0x7f6264bcc228'
+    >>> hex(id('another test'))
+    '0x7f6264bcc260'
+    >>> 
+
 ### Threads
 
 From [GlobalInterpreterLock](https://wiki.python.org/moin/GlobalInterpreterLock):
-- 
GitLab