{
Execution  model  and  
other  must-­‐‑know’s	
“event”:      “Python  BCN  Meetup  –  Beginners  session”	
“author”:  “Pablo  Enfedaque”	
“twi5er”:  “@pablitoev56”
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
>  Today  we  are  going  to  see:	
>  Python  execution  model	
>  Everything  is  an  object	
>  Everything  is  a  pointer  (or  a  reference)	
>  Mutable  vs.  immutable  objects	
Welcome  to  Python!
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
Let’s  start  with  a  simple  module
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
a_simple_module.py	
#-*- coding: utf-8 -*-	
"pybcn basic module example" # Module docstring	
	
from random import randint # An import	
	
	
class MyClass(object): # A class declaration	
def __init__(self, attr1, attr2):	
self.attr1 = attr1	
self.attr2 = attr2	
	
	
def random_instance(): # A function declaration	
"Create an instance of MyClass with random values"	
attr1_val = randint(0, 10)	
attr2_val = randint(0, 10)	
return MyClass(attr1_val, attr2_val)	
	
	
# We execute some statements	
inst = random_instance()	
print "Instance:", inst, inst.attr1, inst.attr2
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
>  Modules  can  contain  any  kind  and  any  number  of  
valid  Python  statements	
>  Classes  declaration	
>  Functions  declaration	
>  Logical  control  constructions  (if,  for,  while...)	
>  Function  calls	
>  Assignments  and  instantiations	
>  Etc.	
Python  modules
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
Let’s  execute  this  module	
me@myhost:~/wspace/beginners$ python a_simple_module.py	
Instance: <__main__.MyClass object at 0x10210b390> 2 5	
	
	
me@myhost:~/wspace/beginners$ python a_simple_module.py	
Instance: <__main__.MyClass object at 0x10104c390> 6 3	
	
	
me@myhost:~/wspace/beginners$ python a_simple_module.py	
Instance: <__main__.MyClass object at 0x11004a390> 9 4
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
Let’s  import  this  module	
me@myhost:~/wspace/beginners$ python	
Python 2.7.5 (default, Aug 25 2013, 00:04:04)	
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin	
Type "help", "copyright", "credits" or "license" for more ...	
	
>>> from a_simple_module import random_instance	
Instance: <a_simple_module.MyClass object at 0x10083b490> 0 4	
	
>>> from a_simple_module import random_instance	
	
>>> another_inst = random_instance()	
	
>>> print another_inst, another_inst.attr1, another_inst.attr2	
<a_simple_module.MyClass object at 0x10083b510> 5 8
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
>  Modules  are  the  basic  unit  of  code  reusability	
>  We  can  reuse  the  content  of  modules  with  import	
Python  modules	
import module_name	
	
from package import module_name	
	
from package.module_name import name	
	
from module_name import name as another_name
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
Let’s  import  again  the  module	
me@myhost:~/wspace/beginners$ python	
Python 2.7.5 (default, Aug 25 2013, 00:04:04)	
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin	
Type "help", "copyright", "credits" or "license" for more ...	
	
>>> from a_simple_module import random_instance	
Instance: <a_simple_module.MyClass object at 0x10083b490> 0 4	
	
>>> from a_simple_module import random_instance	
	
>>> another_inst = random_instance()	
	
>>> print another_inst, another_inst.attr1, another_inst.attr2	
<a_simple_module.MyClass object at 0x10083b510> 5 8	
	
me@myhost:~/wspace/beginners$ python	
Python 2.7.5 (default, Aug 25 2013, 00:04:04)	
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin	
Type "help", "copyright", "credits" or "license" for more ...	
	
>>> from a_simple_module import inst	
Instance: <a_simple_module.MyClass object at 0x10d305490> 6 3
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
	
>  When  a  module  is  imported  for  first  time  Python  
interprets  (executes)  all  its  content	
>  Classes  declaration	
>  Functions  declaration	
>  Logical  control  constructions  (if,  for,  while...)	
>  Function  calls	
>  Assignments  and  instantiations	
>  Etc.	
Python  execution  model
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
Let’s  modify  our  simple  module	
#-*- coding: utf-8 -*-	
"pybcn basic module example”	
	
from random import randint	
	
	
class MyClass(object):	
def __init__(self, attr1, attr2):	
self.attr1 = attr1	
self.attr2 = attr2	
	
	
def random_instance():	
"Create an instance of MyClass with random values"	
attr1_val = randint(0, 10)	
attr2_val = randint(0, 10)	
return MyClass(attr1_val, attr2_val)	
	
	
# We execute some statements	
inst = random_instance()	
print "Instance:", inst, inst.attr1, inst.attr2
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
a_main_module.py	
#-*- coding: utf-8 -*-	
"pybcn main module example”	
	
from random import randint	
	
	
class MyClass(object):	
def __init__(self, attr1, attr2):	
self.attr1 = attr1	
self.attr2 = attr2	
	
	
def random_instance():	
"Create an instance of MyClass with random values"	
attr1_val = randint(0, 10)	
attr2_val = randint(0, 10)	
return MyClass(attr1_val, attr2_val)	
	
	
if __name__ == "__main__": # Only run when module is executed	
inst = random_instance()	
print "Instance:", inst, inst.attr1, inst.attr2
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
Let’s  import  the  new  module	
me@myhost:~/wspace/beginners$ python	
Python 2.7.5 (default, Aug 25 2013, 00:04:04)	
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin	
Type "help", "copyright", "credits" or "license" for more ...	
	
>>> from a_main_module import random_instance	
	
>>> another_inst = random_instance()	
	
>>> print another_inst, another_inst.attr1, another_inst.attr2	
<a_main_module.MyClass object at 0x1082191d0> 4 4	
	
me@myhost:~/wspace/beginners$ python	
Python 2.7.5 (default, Aug 25 2013, 00:04:04)	
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin	
Type "help", "copyright", "credits" or "license" for more ...	
	
>>> from a_main_module import inst	
Traceback (most recent call last):	
File "<stdin>", line 1, in <module>	
ImportError: cannot import name inst
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
>  When  a  module  is  imported  for  first  time  Python  
interprets  (executes)  all  its  content	
>  Check  the  name  of  the  module  in  __name__	
>  This  global  module  a5ribute  has  value  __main__  when  
a  module  is  directly  executed  (instead  of  imported)	
Python  execution  model
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
All  code  is  interpreted,  also  the  if	
#-*- coding: utf-8 -*-	
"pybcn main module example”	
	
from random import randint	
	
	
class MyClass(object):	
def __init__(self, attr1, attr2):	
self.attr1 = attr1	
self.attr2 = attr2	
	
	
def random_instance():	
"Create an instance of MyClass with random values"	
attr1_val = randint(0, 10)	
attr2_val = randint(0, 10)	
return MyClass(attr1_val, attr2_val)	
	
	
if __name__ == "__main__": # Only run when module is executed	
inst = random_instance()	
print "Instance:", inst, inst.attr1, inst.attr2
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
another_module.py	
#-*- coding: utf-8 -*-	
"pybcn another main module example”	
	
from random import randint	
	
	
class MyClass(object):	
def __init__(self, attr1, attr2):	
self.attr1 = attr1	
self.attr2 = attr2	
	
	
def random_instance():	
"Create an instance of MyClass with random values"	
attr1_val = randint(0, 10)	
attr2_val = randint(0, 10)	
return MyClass(attr1_val, attr2_val)	
	
	
if False: # Never interpreted!!	
inst = random_instance()	
print "Instance:", inst, inst.attr1, inst.attr2
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
Let’s  use  this  module	
me@myhost:~/wspace/beginners$ python another_module.py	
	
me@myhost:~/wspace/beginners$ python another_module.py	
	
me@myhost:~/wspace/beginners$ python	
Python 2.7.5 (default, Aug 25 2013, 00:04:04)	
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin	
Type "help", "copyright", "credits" or "license" for more ...	
	
>>> from another_module import random_instance	
	
>>> another_inst = random_instance()	
	
>>> print another_inst, another_inst.attr1, another_inst.attr2	
<another_module.MyClass object at 0x10d6e4510> 10 10	
	
>>> from another_module import inst	
Traceback (most recent call last):	
File "<stdin>", line 1, in <module>	
ImportError: cannot import name inst
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
Ok,  but…	
why  everything  is  interpreted?
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
Let’s  use  the  interpreter	
me@myhost:~/wspace/beginners$ python	
Python 2.7.5 (default, Aug 25 2013, 00:04:04)	
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin	
Type "help", "copyright", "credits" or "license" for more ...	
	
>>> def a_func(arg):	
... "This is a function"	
... return arg + arg	
...	
	
>>> a_func(2)	
4	
	
>>> print a_func.func_doc	
This is a function	
	
>>> print a_func.func_name	
a_func	
	
>>> print type(a_func), isinstance(a_func, object)	
<type 'function'> True
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
>  In  Python  everything  is  an  object	
>  For  Python  there  is  no  difference  between…	
>  An  instantiation  calls  the  class  constructor  and  the  
result  is  a  new  instance  (object)  of  that  class	
>  The  def  keyword  and  all  its  statements  are  interpreted  
and  the  result  is  a  new  function  object	
>  The  class  keyword  and  all  its  statements  are  
interpreted  and  the  result  is  a  new  class  object	
Python  execution  model
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
Everything  is  an  object	
#-*- coding: utf-8 -*-	
"pybcn main module example”	
	
from random import randint	
	
	
class MyClass(object):	
def __init__(self, attr1, attr2):	
self.attr1 = attr1	
self.attr2 = attr2	
	
	
def random_instance():	
"Create an instance of MyClass with random values"	
attr1_val = randint(0, 10)	
attr2_val = randint(0, 10)	
return MyClass(attr1_val, attr2_val)	
	
	
if __name__ == "__main__": # Only run when module is executed	
inst = random_instance()	
print "Instance:", inst, inst.attr1, inst.attr2
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
Everything  is  an  object	
#-*- coding: utf-8 -*-	
"pybcn main module example”	
	
from random import randint	
	
	
class MyClass(object):	
def __init__(self, attr1, attr2):	
self.attr1 = attr1	
self.attr2 = attr2	
	
	
def random_instance():	
"Create an instance of MyClass with random values"	
attr1_val = randint(0, 10)	
attr2_val = randint(0, 10)	
return MyClass(attr1_val, attr2_val)	
	
	
if __name__ == "__main__": # Only run when module is executed	
inst = random_instance()	
print "Instance:", inst, inst.attr1, inst.attr2
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
Let’s  copy  an  object
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
id_function_is_example.py	
#-*- coding: utf-8 -*-	
"pybcn 'id' function and 'is' example"	
	
class MyClass(object):	
def __init__(self, attr1, attr2):	
self.attr1 = attr1	
self.attr2 = attr2	
	
inst1 = MyClass(1, 1)	
inst2 = MyClass(2, 2)	
inst3 = inst1 # Copy	
	
# 'id' function returns the unique identity of an object	
print "Instance 1:", id(inst1), inst1.attr1, inst1.attr2	
print "Instance 2:", id(inst2), inst2.attr1, inst2.attr2	
print "Instance 3:", id(inst3), inst3.attr1, inst3.attr2	
print inst1 is inst3 # 'is' compares the identity
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
Did  we  copy  the  object?	
#-*- coding: utf-8 -*-	
"pybcn 'id' function and 'is' example"	
	
class MyClass(object):	
def __init__(self, attr1, attr2):	
self.attr1 = attr1	
self.attr2 = attr2	
	
inst1 = MyClass(1, 1)	
inst2 = MyClass(2, 2)	
inst3 = inst1 # Copy?	
	
# 'id' function returns the unique identity of an object	
print "Instance 1:", id(inst1), inst1.attr1, inst1.attr2	
print "Instance 2:", id(inst2), inst2.attr1, inst2.attr2	
print "Instance 3:", id(inst3), inst3.attr1, inst3.attr2	
print inst1 is inst3 # 'is' compares the identity	
	
me@myhost:~/wspace/beginners$ python id_function_is_example.py	
Instance 1: 4424626832 1 1	
Instance 2: 4424626896 2 2	
Instance 3: 4424626832 1 1	
True
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
No,  we  just  copied  the  reference
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
>  Every  object  has  an  unchangeable  identity	
>  In  Python  names  are  references  bound  to  an  object	
>  Assignments  only  copy  the  reference  to  an  object	
>  Shallow  copy  is  the  default  behaviour  in  Python	
>  Otherwise,  use  copy.deepcopy  method	
>  Function  calls  only  pass  the  reference  to  the  arguments	
>  You  access  the  same  object  outside  and  inside  a  call	
>  The  same  applies  for  return  values	
Python  execution  model
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
everything_is_a_pointer.py	
#-*- coding: utf-8 -*-	
"pybcn 'everything is a pointer' example"	
	
class MyClass(object):	
def __init__(self, attr1, attr2):	
self.attr1 = attr1	
self.attr2 = attr2	
	
def print_id_and_return(attr):	
print "Attr id:", id(attr)	
return attr	
	
inst = MyClass(3, 4)	
print "Instance:", id(inst)	
	
ret_val = print_id_and_return(inst)	
print inst is ret_val	
	
me@myhost:~/wspace/beginners$ python everything_is_a_pointer.py	
Instance: 4306146128	
Attr id: 4306146128	
True
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
h5p://pythontutor.com/
visualize.html
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
Let’s  modify  some  objects  value
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
modify_objects_value.py	
#-*- coding: utf-8 -*-	
"pybcn modify objects value example”	
	
txt1 = "This is text"	
print id(txt1), txt1	
	
txt2 = txt1 + " and more text" # Which object is txt2?	
print id(txt2), txt2	
print "-" * 5	
	
int1 = 7	
print id(int1), int1	
	
int1 += 11 # Which object is int1?	
print id(int1), int1	
print "-" * 5	
	
list1 = ["a", "b", "c"]	
print id(list1), list1	
	
list1.extend([0, 1, 2]) # In place modification	
list1[0] = "XXX"	
print id(list1), list1
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
Assignment  copies  the  ref.  to  an  object!	
#-*- coding: utf-8 -*-	
"pybcn modify objects value example”	
	
txt1 = "This is text"	
print id(txt1), txt1	
	
txt2 = txt1 + " and more text" # Which object is txt2?	
print id(txt2), txt2	
print "-" * 5	
	
int1 = 7	
print id(int1), int1	
	
int1 += 11 # Which object is int1?	
print id(int1), int1	
print "-" * 5	
	
list1 = ["a", "b", "c"]	
print id(list1), list1	
	
list1.extend([0, 1, 2]) # In place modification	
list1[0] = "XXX"	
print id(list1), list1	
$ python modify_objects_value.py	
	
4335119080 This is text	
4335161776 This is text and more text	
-----	
140435402066344 7	
140435402066080 18	
-----	
4335009736 ['a', 'b', 'c']	
4335009736 ['XXX', 'b', 'c', 0, 1, 2]
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
>  Objects  whose  value  can  change  are  mutable	
>  dicts,  lists,  sets	
>  They  allow  in-­‐‑place  modifications  (append  in  a  list,  
pop  in  a  dictionary...)	
>  They  can  not  be  hashed  (used  as  dict  keys)	
>  Objects  whose  value  is  unchangeable  once  they  
are  created  are  called  immutable	
>  numbers,  strings,  tuples,  NoneType,  boolean	
Mutables  vs.  immutables
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
Ignorance  can  lead  to  bugs...
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
mutables_vs_immutables_1.py	
#-*- coding: utf-8 -*-	
"pybcn mutables assignment bug example”	
	
list1 = ["a", "b", "c"]	
print "list1", list1, "@", id(list1)	
print "-" * 5	
	
list3 = list2 = list1	
list2.append("x")	
print "list1", list1, "@", id(list1)	
print "list2", list2, "@", id(list2)	
print "list3", list3, "@", id(list3)	
print "-" * 5	
	
mtrx1 = [[1, 1, 1], [2, 2, 2]]	
print "mtrx1", mtrx1, "@", id(mtrx1)	
print "-" * 5	
	
mtrx2 = list(mtrx1)	
mtrx2[0].append("a")	
print "mtrx1", mtrx1, "@", id(mtrx1)	
print "mtrx2", mtrx2, "@", id(mtrx2)	
print "-" * 5	
print "mtrx1[0]", mtrx1[0], "@", id(mtrx1[0])	
print "mtrx2[0]", mtrx2[0], "@", id(mtrx2[0])
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
Shallow  copy  uses  ref.  to  same  object	
#-*- coding: utf-8 -*-	
"pybcn mutables assignment bug example”	
	
list1 = ["a", "b", "c"]	
print "list1", list1, "@", id(list1)	
print "-" * 5	
	
list3 = list2 = list1	
list2.append("x")	
print "list1", list1, "@", id(list1)	
print "list2", list2, "@", id(list2)	
print "list3", list3, "@", id(list3)	
print "-" * 5	
	
mtrx1 = [[1, 1, 1], [2, 2, 2]]	
print "mtrx1", mtrx1, "@", id(mtrx1)	
print "-" * 5	
	
mtrx2 = list(mtrx1)	
mtrx2[0].append("a")	
print "mtrx1", mtrx1, "@", id(mtrx1)	
print "mtrx2", mtrx2, "@", id(mtrx2)	
print "-" * 5	
print "mtrx1[0]", mtrx1[0], "@", id(mtrx1[0])	
print "mtrx2[0]", mtrx2[0], "@", id(mtrx2[0])	
$ python mutables_vs_immutables_1.py	
	
list1 ['a', 'b', 'c'] @ 4536893384	
-----	
list1 ['a', 'b', 'c', 'x'] @ 4536893384	
list2 ['a', 'b', 'c', 'x'] @ 4536893384	
list3 ['a', 'b', 'c', 'x'] @ 4536893384	
-----	
mtrx1 [[1, 1, 1], [2, 2, 2]] @ 4537042920	
-----	
mtrx1 [[1, 1, 1, 'a'], [2, 2, 2]] @ 4537042920	
mtrx2 [[1, 1, 1, 'a'], [2, 2, 2]] @ 4537043928	
-----	
mtrx1[0] [1, 1, 1, 'a'] @ 4536943320	
mtrx2[0] [1, 1, 1, 'a'] @ 4536943320
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
mutables_vs_immutables_2.py	
#-*- coding: utf-8 -*-	
"pybcn class attributes bug example"	
	
class ExampleClass(object):	
list_attr = []	
int_attr = 0	
	
instA = ExampleClass()	
instB = ExampleClass()	
	
instA.int_attr += 1	
instA.list_attr.extend([5, 7, 9])	
print "instA.int_attr:", instA.int_attr	
print "instA.list_attr:", instA.list_attr	
print "-" * 5	
	
print "instB.int_attr:", instB.int_attr	
print "instB.list_attr:", instB.list_attr	
	
print "-" * 5	
print instA.list_attr is instB.list_attr	
print ExampleClass.list_attr
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
Class  a5ributes  remain  in  the  class	
#-*- coding: utf-8 -*-	
"pybcn class attributes bug example"	
	
class ExampleClass(object):	
list_attr = []	
int_attr = 0	
	
instA = ExampleClass()	
instB = ExampleClass()	
	
instA.int_attr += 1	
instA.list_attr.extend([5, 7, 9])	
print "instA.int_attr:", instA.int_attr	
print "instA.list_attr:", instA.list_attr	
print "-" * 5	
	
print "instB.int_attr:", instB.int_attr	
print "instB.list_attr:", instB.list_attr	
	
print "-" * 5	
print instA.list_attr is instB.list_attr	
print ExampleClass.list_attr	
$ python mutables_vs_immutables_2.py	
	
instA.int_attr: 1	
instA.list_attr: [5, 7, 9]	
-----	
instB.int_attr: 0	
instB.list_attr: [5, 7, 9]	
-----	
True	
[5, 7, 9]
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
mutables_vs_immutables_3.py	
#-*- coding: utf-8 -*-	
"pybcn function default attribute bug example"	
	
def add_power_to_list(item, powers_lst=[]):	
powers_lst.append(item ** 2)	
return powers_lst	
	
print "default:", add_power_to_list.func_defaults	
print "-" * 5	
	
result1 = add_power_to_list(2)	
print "result1:", result1	
print "-" * 5	
	
result2 = add_power_to_list(3)	
print "result1:", result1, 'vs', "result2", result2	
print result1 is result2	
print "-" * 5	
	
print "default:", add_power_to_list.func_defaults
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
Functions  default  values  remain  in  
the  function	
#-*- coding: utf-8 -*-	
"pybcn function default attribute bug example"	
	
def add_power_to_list(item, powers_lst=[]):	
powers_lst.append(item ** 2)	
return powers_lst	
	
print "default:", add_power_to_list.func_defaults	
print "-" * 5	
	
result1 = add_power_to_list(2)	
print "result1:", result1	
print "-" * 5	
	
result2 = add_power_to_list(3)	
print "result1:", result1, 'vs', "result2", result2	
print result1 is result2	
print "-" * 5	
	
print "default:", add_power_to_list.func_defaults	
$ python mutables_vs_immutables_3.py	
default: ([],)	
-----	
result1: [4]	
-----	
result1: [4, 9] vs result2 [4, 9]	
True	
-----	
default: ([4, 9],)
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
>  Shallow  copy  uses  the  reference  to  the  object	
>  Assignment,  constructor  by  copy,  arguments  in  function  calls	
>  Be  aware  of  it	
>  Class  a5ributes  remain  in  the  class	
>  Create  instance  mutable  aPributes  in  __init__	
>  Functions  default  values  remain  in  the  function	
>  Create  mutable  default  values  inside  the  function	
Mutables  vs.  immutables  bugs
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
>  Modules  can  contain  anything	
>  All  lines  of  code  are  interpreted	
>  Check  __name__	
>  Everything  is  an  object	
>  Names  are  pointers  bound  to  objects	
>  Mutable  and  immutable  objects	
>  Take  care  with  common  bugs	
Conclusions
{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}	
	
Q&A	
Thanks  for  coming!	
	
	
Slides:  
h5ps://speakerdeck.com/pablito56/
execution-­‐‑model-­‐‑and-­‐‑other-­‐‑must-­‐‑knows  	
Code:  
h5ps://github.com/pablito56/pybcn-­‐‑
beginners  

Execution model and other must-know's

  • 1.
    { Execution  model  and  other  must-­‐‑know’s “event”:      “Python  BCN  Meetup  –  Beginners  session” “author”:  “Pablo  Enfedaque” “twi5er”:  “@pablitoev56”
  • 2.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} >  Today  we  are  going  to  see: >  Python  execution  model >  Everything  is  an  object >  Everything  is  a  pointer  (or  a  reference) >  Mutable  vs.  immutable  objects Welcome  to  Python!
  • 3.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} Let’s  start  with  a  simple  module
  • 4.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} a_simple_module.py #-*- coding: utf-8 -*- "pybcn basic module example" # Module docstring from random import randint # An import class MyClass(object): # A class declaration def __init__(self, attr1, attr2): self.attr1 = attr1 self.attr2 = attr2 def random_instance(): # A function declaration "Create an instance of MyClass with random values" attr1_val = randint(0, 10) attr2_val = randint(0, 10) return MyClass(attr1_val, attr2_val) # We execute some statements inst = random_instance() print "Instance:", inst, inst.attr1, inst.attr2
  • 5.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} >  Modules  can  contain  any  kind  and  any  number  of   valid  Python  statements >  Classes  declaration >  Functions  declaration >  Logical  control  constructions  (if,  for,  while...) >  Function  calls >  Assignments  and  instantiations >  Etc. Python  modules
  • 6.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} Let’s  execute  this  module me@myhost:~/wspace/beginners$ python a_simple_module.py Instance: <__main__.MyClass object at 0x10210b390> 2 5 me@myhost:~/wspace/beginners$ python a_simple_module.py Instance: <__main__.MyClass object at 0x10104c390> 6 3 me@myhost:~/wspace/beginners$ python a_simple_module.py Instance: <__main__.MyClass object at 0x11004a390> 9 4
  • 7.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} Let’s  import  this  module me@myhost:~/wspace/beginners$ python Python 2.7.5 (default, Aug 25 2013, 00:04:04) [GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin Type "help", "copyright", "credits" or "license" for more ... >>> from a_simple_module import random_instance Instance: <a_simple_module.MyClass object at 0x10083b490> 0 4 >>> from a_simple_module import random_instance >>> another_inst = random_instance() >>> print another_inst, another_inst.attr1, another_inst.attr2 <a_simple_module.MyClass object at 0x10083b510> 5 8
  • 8.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} >  Modules  are  the  basic  unit  of  code  reusability >  We  can  reuse  the  content  of  modules  with  import Python  modules import module_name from package import module_name from package.module_name import name from module_name import name as another_name
  • 9.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} Let’s  import  again  the  module me@myhost:~/wspace/beginners$ python Python 2.7.5 (default, Aug 25 2013, 00:04:04) [GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin Type "help", "copyright", "credits" or "license" for more ... >>> from a_simple_module import random_instance Instance: <a_simple_module.MyClass object at 0x10083b490> 0 4 >>> from a_simple_module import random_instance >>> another_inst = random_instance() >>> print another_inst, another_inst.attr1, another_inst.attr2 <a_simple_module.MyClass object at 0x10083b510> 5 8 me@myhost:~/wspace/beginners$ python Python 2.7.5 (default, Aug 25 2013, 00:04:04) [GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin Type "help", "copyright", "credits" or "license" for more ... >>> from a_simple_module import inst Instance: <a_simple_module.MyClass object at 0x10d305490> 6 3
  • 10.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} >  When  a  module  is  imported  for  first  time  Python   interprets  (executes)  all  its  content >  Classes  declaration >  Functions  declaration >  Logical  control  constructions  (if,  for,  while...) >  Function  calls >  Assignments  and  instantiations >  Etc. Python  execution  model
  • 11.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} Let’s  modify  our  simple  module #-*- coding: utf-8 -*- "pybcn basic module example” from random import randint class MyClass(object): def __init__(self, attr1, attr2): self.attr1 = attr1 self.attr2 = attr2 def random_instance(): "Create an instance of MyClass with random values" attr1_val = randint(0, 10) attr2_val = randint(0, 10) return MyClass(attr1_val, attr2_val) # We execute some statements inst = random_instance() print "Instance:", inst, inst.attr1, inst.attr2
  • 12.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} a_main_module.py #-*- coding: utf-8 -*- "pybcn main module example” from random import randint class MyClass(object): def __init__(self, attr1, attr2): self.attr1 = attr1 self.attr2 = attr2 def random_instance(): "Create an instance of MyClass with random values" attr1_val = randint(0, 10) attr2_val = randint(0, 10) return MyClass(attr1_val, attr2_val) if __name__ == "__main__": # Only run when module is executed inst = random_instance() print "Instance:", inst, inst.attr1, inst.attr2
  • 13.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} Let’s  import  the  new  module me@myhost:~/wspace/beginners$ python Python 2.7.5 (default, Aug 25 2013, 00:04:04) [GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin Type "help", "copyright", "credits" or "license" for more ... >>> from a_main_module import random_instance >>> another_inst = random_instance() >>> print another_inst, another_inst.attr1, another_inst.attr2 <a_main_module.MyClass object at 0x1082191d0> 4 4 me@myhost:~/wspace/beginners$ python Python 2.7.5 (default, Aug 25 2013, 00:04:04) [GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin Type "help", "copyright", "credits" or "license" for more ... >>> from a_main_module import inst Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: cannot import name inst
  • 14.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} >  When  a  module  is  imported  for  first  time  Python   interprets  (executes)  all  its  content >  Check  the  name  of  the  module  in  __name__ >  This  global  module  a5ribute  has  value  __main__  when   a  module  is  directly  executed  (instead  of  imported) Python  execution  model
  • 15.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} All  code  is  interpreted,  also  the  if #-*- coding: utf-8 -*- "pybcn main module example” from random import randint class MyClass(object): def __init__(self, attr1, attr2): self.attr1 = attr1 self.attr2 = attr2 def random_instance(): "Create an instance of MyClass with random values" attr1_val = randint(0, 10) attr2_val = randint(0, 10) return MyClass(attr1_val, attr2_val) if __name__ == "__main__": # Only run when module is executed inst = random_instance() print "Instance:", inst, inst.attr1, inst.attr2
  • 16.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} another_module.py #-*- coding: utf-8 -*- "pybcn another main module example” from random import randint class MyClass(object): def __init__(self, attr1, attr2): self.attr1 = attr1 self.attr2 = attr2 def random_instance(): "Create an instance of MyClass with random values" attr1_val = randint(0, 10) attr2_val = randint(0, 10) return MyClass(attr1_val, attr2_val) if False: # Never interpreted!! inst = random_instance() print "Instance:", inst, inst.attr1, inst.attr2
  • 17.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} Let’s  use  this  module me@myhost:~/wspace/beginners$ python another_module.py me@myhost:~/wspace/beginners$ python another_module.py me@myhost:~/wspace/beginners$ python Python 2.7.5 (default, Aug 25 2013, 00:04:04) [GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin Type "help", "copyright", "credits" or "license" for more ... >>> from another_module import random_instance >>> another_inst = random_instance() >>> print another_inst, another_inst.attr1, another_inst.attr2 <another_module.MyClass object at 0x10d6e4510> 10 10 >>> from another_module import inst Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: cannot import name inst
  • 18.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} Ok,  but… why  everything  is  interpreted?
  • 19.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} Let’s  use  the  interpreter me@myhost:~/wspace/beginners$ python Python 2.7.5 (default, Aug 25 2013, 00:04:04) [GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin Type "help", "copyright", "credits" or "license" for more ... >>> def a_func(arg): ... "This is a function" ... return arg + arg ... >>> a_func(2) 4 >>> print a_func.func_doc This is a function >>> print a_func.func_name a_func >>> print type(a_func), isinstance(a_func, object) <type 'function'> True
  • 20.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} >  In  Python  everything  is  an  object >  For  Python  there  is  no  difference  between… >  An  instantiation  calls  the  class  constructor  and  the   result  is  a  new  instance  (object)  of  that  class >  The  def  keyword  and  all  its  statements  are  interpreted   and  the  result  is  a  new  function  object >  The  class  keyword  and  all  its  statements  are   interpreted  and  the  result  is  a  new  class  object Python  execution  model
  • 21.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} Everything  is  an  object #-*- coding: utf-8 -*- "pybcn main module example” from random import randint class MyClass(object): def __init__(self, attr1, attr2): self.attr1 = attr1 self.attr2 = attr2 def random_instance(): "Create an instance of MyClass with random values" attr1_val = randint(0, 10) attr2_val = randint(0, 10) return MyClass(attr1_val, attr2_val) if __name__ == "__main__": # Only run when module is executed inst = random_instance() print "Instance:", inst, inst.attr1, inst.attr2
  • 22.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} Everything  is  an  object #-*- coding: utf-8 -*- "pybcn main module example” from random import randint class MyClass(object): def __init__(self, attr1, attr2): self.attr1 = attr1 self.attr2 = attr2 def random_instance(): "Create an instance of MyClass with random values" attr1_val = randint(0, 10) attr2_val = randint(0, 10) return MyClass(attr1_val, attr2_val) if __name__ == "__main__": # Only run when module is executed inst = random_instance() print "Instance:", inst, inst.attr1, inst.attr2
  • 23.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} Let’s  copy  an  object
  • 24.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} id_function_is_example.py #-*- coding: utf-8 -*- "pybcn 'id' function and 'is' example" class MyClass(object): def __init__(self, attr1, attr2): self.attr1 = attr1 self.attr2 = attr2 inst1 = MyClass(1, 1) inst2 = MyClass(2, 2) inst3 = inst1 # Copy # 'id' function returns the unique identity of an object print "Instance 1:", id(inst1), inst1.attr1, inst1.attr2 print "Instance 2:", id(inst2), inst2.attr1, inst2.attr2 print "Instance 3:", id(inst3), inst3.attr1, inst3.attr2 print inst1 is inst3 # 'is' compares the identity
  • 25.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} Did  we  copy  the  object? #-*- coding: utf-8 -*- "pybcn 'id' function and 'is' example" class MyClass(object): def __init__(self, attr1, attr2): self.attr1 = attr1 self.attr2 = attr2 inst1 = MyClass(1, 1) inst2 = MyClass(2, 2) inst3 = inst1 # Copy? # 'id' function returns the unique identity of an object print "Instance 1:", id(inst1), inst1.attr1, inst1.attr2 print "Instance 2:", id(inst2), inst2.attr1, inst2.attr2 print "Instance 3:", id(inst3), inst3.attr1, inst3.attr2 print inst1 is inst3 # 'is' compares the identity me@myhost:~/wspace/beginners$ python id_function_is_example.py Instance 1: 4424626832 1 1 Instance 2: 4424626896 2 2 Instance 3: 4424626832 1 1 True
  • 26.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} No,  we  just  copied  the  reference
  • 27.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} >  Every  object  has  an  unchangeable  identity >  In  Python  names  are  references  bound  to  an  object >  Assignments  only  copy  the  reference  to  an  object >  Shallow  copy  is  the  default  behaviour  in  Python >  Otherwise,  use  copy.deepcopy  method >  Function  calls  only  pass  the  reference  to  the  arguments >  You  access  the  same  object  outside  and  inside  a  call >  The  same  applies  for  return  values Python  execution  model
  • 28.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} everything_is_a_pointer.py #-*- coding: utf-8 -*- "pybcn 'everything is a pointer' example" class MyClass(object): def __init__(self, attr1, attr2): self.attr1 = attr1 self.attr2 = attr2 def print_id_and_return(attr): print "Attr id:", id(attr) return attr inst = MyClass(3, 4) print "Instance:", id(inst) ret_val = print_id_and_return(inst) print inst is ret_val me@myhost:~/wspace/beginners$ python everything_is_a_pointer.py Instance: 4306146128 Attr id: 4306146128 True
  • 29.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} h5p://pythontutor.com/ visualize.html
  • 30.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} Let’s  modify  some  objects  value
  • 31.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} modify_objects_value.py #-*- coding: utf-8 -*- "pybcn modify objects value example” txt1 = "This is text" print id(txt1), txt1 txt2 = txt1 + " and more text" # Which object is txt2? print id(txt2), txt2 print "-" * 5 int1 = 7 print id(int1), int1 int1 += 11 # Which object is int1? print id(int1), int1 print "-" * 5 list1 = ["a", "b", "c"] print id(list1), list1 list1.extend([0, 1, 2]) # In place modification list1[0] = "XXX" print id(list1), list1
  • 32.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} Assignment  copies  the  ref.  to  an  object! #-*- coding: utf-8 -*- "pybcn modify objects value example” txt1 = "This is text" print id(txt1), txt1 txt2 = txt1 + " and more text" # Which object is txt2? print id(txt2), txt2 print "-" * 5 int1 = 7 print id(int1), int1 int1 += 11 # Which object is int1? print id(int1), int1 print "-" * 5 list1 = ["a", "b", "c"] print id(list1), list1 list1.extend([0, 1, 2]) # In place modification list1[0] = "XXX" print id(list1), list1 $ python modify_objects_value.py 4335119080 This is text 4335161776 This is text and more text ----- 140435402066344 7 140435402066080 18 ----- 4335009736 ['a', 'b', 'c'] 4335009736 ['XXX', 'b', 'c', 0, 1, 2]
  • 33.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} >  Objects  whose  value  can  change  are  mutable >  dicts,  lists,  sets >  They  allow  in-­‐‑place  modifications  (append  in  a  list,   pop  in  a  dictionary...) >  They  can  not  be  hashed  (used  as  dict  keys) >  Objects  whose  value  is  unchangeable  once  they   are  created  are  called  immutable >  numbers,  strings,  tuples,  NoneType,  boolean Mutables  vs.  immutables
  • 34.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} Ignorance  can  lead  to  bugs...
  • 35.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} mutables_vs_immutables_1.py #-*- coding: utf-8 -*- "pybcn mutables assignment bug example” list1 = ["a", "b", "c"] print "list1", list1, "@", id(list1) print "-" * 5 list3 = list2 = list1 list2.append("x") print "list1", list1, "@", id(list1) print "list2", list2, "@", id(list2) print "list3", list3, "@", id(list3) print "-" * 5 mtrx1 = [[1, 1, 1], [2, 2, 2]] print "mtrx1", mtrx1, "@", id(mtrx1) print "-" * 5 mtrx2 = list(mtrx1) mtrx2[0].append("a") print "mtrx1", mtrx1, "@", id(mtrx1) print "mtrx2", mtrx2, "@", id(mtrx2) print "-" * 5 print "mtrx1[0]", mtrx1[0], "@", id(mtrx1[0]) print "mtrx2[0]", mtrx2[0], "@", id(mtrx2[0])
  • 36.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} Shallow  copy  uses  ref.  to  same  object #-*- coding: utf-8 -*- "pybcn mutables assignment bug example” list1 = ["a", "b", "c"] print "list1", list1, "@", id(list1) print "-" * 5 list3 = list2 = list1 list2.append("x") print "list1", list1, "@", id(list1) print "list2", list2, "@", id(list2) print "list3", list3, "@", id(list3) print "-" * 5 mtrx1 = [[1, 1, 1], [2, 2, 2]] print "mtrx1", mtrx1, "@", id(mtrx1) print "-" * 5 mtrx2 = list(mtrx1) mtrx2[0].append("a") print "mtrx1", mtrx1, "@", id(mtrx1) print "mtrx2", mtrx2, "@", id(mtrx2) print "-" * 5 print "mtrx1[0]", mtrx1[0], "@", id(mtrx1[0]) print "mtrx2[0]", mtrx2[0], "@", id(mtrx2[0]) $ python mutables_vs_immutables_1.py list1 ['a', 'b', 'c'] @ 4536893384 ----- list1 ['a', 'b', 'c', 'x'] @ 4536893384 list2 ['a', 'b', 'c', 'x'] @ 4536893384 list3 ['a', 'b', 'c', 'x'] @ 4536893384 ----- mtrx1 [[1, 1, 1], [2, 2, 2]] @ 4537042920 ----- mtrx1 [[1, 1, 1, 'a'], [2, 2, 2]] @ 4537042920 mtrx2 [[1, 1, 1, 'a'], [2, 2, 2]] @ 4537043928 ----- mtrx1[0] [1, 1, 1, 'a'] @ 4536943320 mtrx2[0] [1, 1, 1, 'a'] @ 4536943320
  • 37.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} mutables_vs_immutables_2.py #-*- coding: utf-8 -*- "pybcn class attributes bug example" class ExampleClass(object): list_attr = [] int_attr = 0 instA = ExampleClass() instB = ExampleClass() instA.int_attr += 1 instA.list_attr.extend([5, 7, 9]) print "instA.int_attr:", instA.int_attr print "instA.list_attr:", instA.list_attr print "-" * 5 print "instB.int_attr:", instB.int_attr print "instB.list_attr:", instB.list_attr print "-" * 5 print instA.list_attr is instB.list_attr print ExampleClass.list_attr
  • 38.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} Class  a5ributes  remain  in  the  class #-*- coding: utf-8 -*- "pybcn class attributes bug example" class ExampleClass(object): list_attr = [] int_attr = 0 instA = ExampleClass() instB = ExampleClass() instA.int_attr += 1 instA.list_attr.extend([5, 7, 9]) print "instA.int_attr:", instA.int_attr print "instA.list_attr:", instA.list_attr print "-" * 5 print "instB.int_attr:", instB.int_attr print "instB.list_attr:", instB.list_attr print "-" * 5 print instA.list_attr is instB.list_attr print ExampleClass.list_attr $ python mutables_vs_immutables_2.py instA.int_attr: 1 instA.list_attr: [5, 7, 9] ----- instB.int_attr: 0 instB.list_attr: [5, 7, 9] ----- True [5, 7, 9]
  • 39.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} mutables_vs_immutables_3.py #-*- coding: utf-8 -*- "pybcn function default attribute bug example" def add_power_to_list(item, powers_lst=[]): powers_lst.append(item ** 2) return powers_lst print "default:", add_power_to_list.func_defaults print "-" * 5 result1 = add_power_to_list(2) print "result1:", result1 print "-" * 5 result2 = add_power_to_list(3) print "result1:", result1, 'vs', "result2", result2 print result1 is result2 print "-" * 5 print "default:", add_power_to_list.func_defaults
  • 40.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} Functions  default  values  remain  in   the  function #-*- coding: utf-8 -*- "pybcn function default attribute bug example" def add_power_to_list(item, powers_lst=[]): powers_lst.append(item ** 2) return powers_lst print "default:", add_power_to_list.func_defaults print "-" * 5 result1 = add_power_to_list(2) print "result1:", result1 print "-" * 5 result2 = add_power_to_list(3) print "result1:", result1, 'vs', "result2", result2 print result1 is result2 print "-" * 5 print "default:", add_power_to_list.func_defaults $ python mutables_vs_immutables_3.py default: ([],) ----- result1: [4] ----- result1: [4, 9] vs result2 [4, 9] True ----- default: ([4, 9],)
  • 41.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} >  Shallow  copy  uses  the  reference  to  the  object >  Assignment,  constructor  by  copy,  arguments  in  function  calls >  Be  aware  of  it >  Class  a5ributes  remain  in  the  class >  Create  instance  mutable  aPributes  in  __init__ >  Functions  default  values  remain  in  the  function >  Create  mutable  default  values  inside  the  function Mutables  vs.  immutables  bugs
  • 42.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} >  Modules  can  contain  anything >  All  lines  of  code  are  interpreted >  Check  __name__ >  Everything  is  an  object >  Names  are  pointers  bound  to  objects >  Mutable  and  immutable  objects >  Take  care  with  common  bugs Conclusions
  • 43.
    {  “event”:  “Python BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”} Q&A Thanks  for  coming! Slides:   h5ps://speakerdeck.com/pablito56/ execution-­‐‑model-­‐‑and-­‐‑other-­‐‑must-­‐‑knows   Code:   h5ps://github.com/pablito56/pybcn-­‐‑ beginners