execution model and other must-know's

43
{ Execution model and other mustknow’s “event”: Python BCN Meetup – Beginners session“author”: “Pablo Enfedaque“twi5er”: “@pablitoev56

Upload: pablo-enfedaque

Post on 30-Oct-2014

155 views

Category:

Technology


1 download

DESCRIPTION

Session in Python Bcn Meetup, Beginners session >> Contents: - Python execution model - Everything is an object - Everything is a pointer (or a reference) - Mutable vs. immutable objects - Common errors >> Code examples: https://github.com/pablito56/pybcn-beginners

TRANSCRIPT

Page 1: Execution model and other must-know's

{Execution  model  and  

other  must-­‐‑know’s “event”:      “Python  BCN  Meetup  –  Beginners  session” “author”:  “Pablo  Enfedaque” “twi5er”:  “@pablitoev56”

Page 2: Execution model and other must-know's

{  “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!

Page 3: Execution model and other must-know's

{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}

Let’s  start  with  a  simple  module

Page 4: Execution model and other must-know's

{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}

a_simple_module.py

#-*- coding: utf-8 -*-"pybcn basic module example" # Module docstringfrom random import randint # An importclass MyClass(object): # A class declaration def __init__(self, attr1, attr2): self.attr1 = attr1 self.attr2 = attr2def 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 statementsinst = random_instance()print "Instance:", inst, inst.attr1, inst.attr2

Page 5: Execution model and other must-know's

{  “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

Page 6: Execution model and other must-know's

{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}

Let’s  execute  this  module

me@myhost:~/wspace/beginners$ python a_simple_module.pyInstance: <__main__.MyClass object at 0x10210b390> 2 5me@myhost:~/wspace/beginners$ python a_simple_module.pyInstance: <__main__.MyClass object at 0x10104c390> 6 3me@myhost:~/wspace/beginners$ python a_simple_module.pyInstance: <__main__.MyClass object at 0x11004a390> 9 4

Page 7: Execution model and other must-know's

{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}

Let’s  import  this  module

me@myhost:~/wspace/beginners$ pythonPython 2.7.5 (default, Aug 25 2013, 00:04:04)[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwinType "help", "copyright", "credits" or "license" for more ...>>> from a_simple_module import random_instanceInstance: <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

Page 8: Execution model and other must-know's

{  “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_namefrom package import module_namefrom package.module_name import namefrom module_name import name as another_name

Page 9: Execution model and other must-know's

{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}

Let’s  import  again  the  module

me@myhost:~/wspace/beginners$ pythonPython 2.7.5 (default, Aug 25 2013, 00:04:04)[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwinType "help", "copyright", "credits" or "license" for more ...>>> from a_simple_module import random_instanceInstance: <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 8me@myhost:~/wspace/beginners$ pythonPython 2.7.5 (default, Aug 25 2013, 00:04:04)[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwinType "help", "copyright", "credits" or "license" for more ...>>> from a_simple_module import instInstance: <a_simple_module.MyClass object at 0x10d305490> 6 3

Page 10: Execution model and other must-know's

{  “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

Page 11: Execution model and other must-know's

{  “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 randintclass MyClass(object): def __init__(self, attr1, attr2): self.attr1 = attr1 self.attr2 = attr2def 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 statementsinst = random_instance()print "Instance:", inst, inst.attr1, inst.attr2

Page 12: Execution model and other must-know's

{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}

a_main_module.py

#-*- coding: utf-8 -*-"pybcn main module example”from random import randintclass MyClass(object): def __init__(self, attr1, attr2): self.attr1 = attr1 self.attr2 = attr2def 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

Page 13: Execution model and other must-know's

{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}

Let’s  import  the  new  module

me@myhost:~/wspace/beginners$ pythonPython 2.7.5 (default, Aug 25 2013, 00:04:04)[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwinType "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 4me@myhost:~/wspace/beginners$ pythonPython 2.7.5 (default, Aug 25 2013, 00:04:04)[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwinType "help", "copyright", "credits" or "license" for more ...>>> from a_main_module import instTraceback (most recent call last): File "<stdin>", line 1, in <module>ImportError: cannot import name inst

Page 14: Execution model and other must-know's

{  “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

Page 15: Execution model and other must-know's

{  “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 randintclass MyClass(object): def __init__(self, attr1, attr2): self.attr1 = attr1 self.attr2 = attr2def 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

Page 16: Execution model and other must-know's

{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}

another_module.py

#-*- coding: utf-8 -*-"pybcn another main module example”from random import randintclass MyClass(object): def __init__(self, attr1, attr2): self.attr1 = attr1 self.attr2 = attr2def 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

Page 17: Execution model and other must-know's

{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}

Let’s  use  this  module

me@myhost:~/wspace/beginners$ python another_module.pyme@myhost:~/wspace/beginners$ python another_module.pyme@myhost:~/wspace/beginners$ pythonPython 2.7.5 (default, Aug 25 2013, 00:04:04)[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwinType "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 instTraceback (most recent call last): File "<stdin>", line 1, in <module>ImportError: cannot import name inst

Page 18: Execution model and other must-know's

{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}

Ok,  but… why  everything  is  interpreted?

Page 19: Execution model and other must-know's

{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}

Let’s  use  the  interpreter

me@myhost:~/wspace/beginners$ pythonPython 2.7.5 (default, Aug 25 2013, 00:04:04)[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwinType "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_docThis is a function>>> print a_func.func_namea_func>>> print type(a_func), isinstance(a_func, object)<type 'function'> True

Page 20: Execution model and other must-know's

{  “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

Page 21: Execution model and other must-know's

{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}

Everything  is  an  object

#-*- coding: utf-8 -*-"pybcn main module example”from random import randintclass MyClass(object): def __init__(self, attr1, attr2): self.attr1 = attr1 self.attr2 = attr2def 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

Page 22: Execution model and other must-know's

{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}

Everything  is  an  object

#-*- coding: utf-8 -*-"pybcn main module example”from random import randintclass MyClass(object): def __init__(self, attr1, attr2): self.attr1 = attr1 self.attr2 = attr2def 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

Page 23: Execution model and other must-know's

{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}

Let’s  copy  an  object

Page 24: Execution model and other must-know's

{  “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 = attr2inst1 = MyClass(1, 1)inst2 = MyClass(2, 2)inst3 = inst1 # Copy# 'id' function returns the unique identity of an objectprint "Instance 1:", id(inst1), inst1.attr1, inst1.attr2print "Instance 2:", id(inst2), inst2.attr1, inst2.attr2print "Instance 3:", id(inst3), inst3.attr1, inst3.attr2print inst1 is inst3 # 'is' compares the identity

Page 25: Execution model and other must-know's

{  “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 = attr2inst1 = MyClass(1, 1)inst2 = MyClass(2, 2)inst3 = inst1 # Copy?# 'id' function returns the unique identity of an objectprint "Instance 1:", id(inst1), inst1.attr1, inst1.attr2print "Instance 2:", id(inst2), inst2.attr1, inst2.attr2print "Instance 3:", id(inst3), inst3.attr1, inst3.attr2print inst1 is inst3 # 'is' compares the identityme@myhost:~/wspace/beginners$ python id_function_is_example.pyInstance 1: 4424626832 1 1Instance 2: 4424626896 2 2Instance 3: 4424626832 1 1True

Page 26: Execution model and other must-know's

{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}

No,  we  just  copied  the  reference

Page 27: Execution model and other must-know's

{  “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

Page 28: Execution model and other must-know's

{  “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 = attr2def print_id_and_return(attr): print "Attr id:", id(attr) return attrinst = MyClass(3, 4)print "Instance:", id(inst)ret_val = print_id_and_return(inst)print inst is ret_valme@myhost:~/wspace/beginners$ python everything_is_a_pointer.pyInstance: 4306146128Attr id: 4306146128True

Page 29: Execution model and other must-know's

{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}

h5p://pythontutor.com/visualize.html

Page 30: Execution model and other must-know's

{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}

Let’s  modify  some  objects  value

Page 31: Execution model and other must-know's

{  “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), txt1txt2 = txt1 + " and more text" # Which object is txt2?print id(txt2), txt2print "-" * 5int1 = 7print id(int1), int1int1 += 11 # Which object is int1?print id(int1), int1print "-" * 5list1 = ["a", "b", "c"]print id(list1), list1list1.extend([0, 1, 2]) # In place modificationlist1[0] = "XXX"print id(list1), list1

Page 32: Execution model and other must-know's

{  “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), txt1txt2 = txt1 + " and more text" # Which object is txt2?print id(txt2), txt2print "-" * 5int1 = 7print id(int1), int1int1 += 11 # Which object is int1?print id(int1), int1print "-" * 5list1 = ["a", "b", "c"]print id(list1), list1list1.extend([0, 1, 2]) # In place modificationlist1[0] = "XXX"print id(list1), list1

$ python modify_objects_value.py4335119080 This is text4335161776 This is text and more text-----140435402066344 7140435402066080 18-----4335009736 ['a', 'b', 'c']4335009736 ['XXX', 'b', 'c', 0, 1, 2]

Page 33: Execution model and other must-know's

{  “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

Page 34: Execution model and other must-know's

{  “event”:  “Python  BCN  Meetup”,  “author”:  “Pablo  Enfedaque”,  “twi5er”:  “@pablitoev56”}

Ignorance  can  lead  to  bugs...

Page 35: Execution model and other must-know's

{  “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 "-" * 5list3 = list2 = list1list2.append("x")print "list1", list1, "@", id(list1)print "list2", list2, "@", id(list2)print "list3", list3, "@", id(list3)print "-" * 5mtrx1 = [[1, 1, 1], [2, 2, 2]]print "mtrx1", mtrx1, "@", id(mtrx1)print "-" * 5mtrx2 = list(mtrx1)mtrx2[0].append("a")print "mtrx1", mtrx1, "@", id(mtrx1)print "mtrx2", mtrx2, "@", id(mtrx2)print "-" * 5print "mtrx1[0]", mtrx1[0], "@", id(mtrx1[0])print "mtrx2[0]", mtrx2[0], "@", id(mtrx2[0])

Page 36: Execution model and other must-know's

{  “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 "-" * 5list3 = list2 = list1list2.append("x")print "list1", list1, "@", id(list1)print "list2", list2, "@", id(list2)print "list3", list3, "@", id(list3)print "-" * 5mtrx1 = [[1, 1, 1], [2, 2, 2]]print "mtrx1", mtrx1, "@", id(mtrx1)print "-" * 5mtrx2 = list(mtrx1)mtrx2[0].append("a")print "mtrx1", mtrx1, "@", id(mtrx1)print "mtrx2", mtrx2, "@", id(mtrx2)print "-" * 5print "mtrx1[0]", mtrx1[0], "@", id(mtrx1[0])print "mtrx2[0]", mtrx2[0], "@", id(mtrx2[0])

$ python mutables_vs_immutables_1.pylist1 ['a', 'b', 'c'] @ 4536893384-----list1 ['a', 'b', 'c', 'x'] @ 4536893384list2 ['a', 'b', 'c', 'x'] @ 4536893384list3 ['a', 'b', 'c', 'x'] @ 4536893384-----mtrx1 [[1, 1, 1], [2, 2, 2]] @ 4537042920-----mtrx1 [[1, 1, 1, 'a'], [2, 2, 2]] @ 4537042920mtrx2 [[1, 1, 1, 'a'], [2, 2, 2]] @ 4537043928-----mtrx1[0] [1, 1, 1, 'a'] @ 4536943320mtrx2[0] [1, 1, 1, 'a'] @ 4536943320

Page 37: Execution model and other must-know's

{  “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 = 0instA = ExampleClass()instB = ExampleClass()instA.int_attr += 1instA.list_attr.extend([5, 7, 9])print "instA.int_attr:", instA.int_attrprint "instA.list_attr:", instA.list_attrprint "-" * 5print "instB.int_attr:", instB.int_attrprint "instB.list_attr:", instB.list_attrprint "-" * 5print instA.list_attr is instB.list_attrprint ExampleClass.list_attr

Page 38: Execution model and other must-know's

{  “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 = 0instA = ExampleClass()instB = ExampleClass()instA.int_attr += 1instA.list_attr.extend([5, 7, 9])print "instA.int_attr:", instA.int_attrprint "instA.list_attr:", instA.list_attrprint "-" * 5print "instB.int_attr:", instB.int_attrprint "instB.list_attr:", instB.list_attrprint "-" * 5print instA.list_attr is instB.list_attrprint ExampleClass.list_attr

$ python mutables_vs_immutables_2.pyinstA.int_attr: 1instA.list_attr: [5, 7, 9]-----instB.int_attr: 0instB.list_attr: [5, 7, 9]-----True[5, 7, 9]

Page 39: Execution model and other must-know's

{  “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_lstprint "default:", add_power_to_list.func_defaultsprint "-" * 5result1 = add_power_to_list(2)print "result1:", result1print "-" * 5result2 = add_power_to_list(3)print "result1:", result1, 'vs', "result2", result2print result1 is result2print "-" * 5print "default:", add_power_to_list.func_defaults

Page 40: Execution model and other must-know's

{  “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_lstprint "default:", add_power_to_list.func_defaultsprint "-" * 5result1 = add_power_to_list(2)print "result1:", result1print "-" * 5result2 = add_power_to_list(3)print "result1:", result1, 'vs', "result2", result2print result1 is result2print "-" * 5print "default:", add_power_to_list.func_defaults

$ python mutables_vs_immutables_3.pydefault: ([],)-----result1: [4]-----result1: [4, 9] vs result2 [4, 9]True-----default: ([4, 9],)

Page 41: Execution model and other must-know's

{  “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

Page 42: Execution model and other must-know's

{  “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

Page 43: Execution model and other must-know's

{  “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