Python Variables

Following up on my previous post, in this one I will writing mostly on variables, scopes, modules

Variables

  • Variables are name, not containers
    • Everything is an object
    • Everything is a reference
    • Variables are neither
    • They are not allocated memory that holds data, they are neither objects or references they are only labels
  • Everything concrete is an object
    • Whenever you hold an object, whenever you store it anywhere you are storing a reference, you dont own an object, you just own their reference.
  • Everything that holds anything, holds references
  • Variables refers to objects
    • namespaces maps names to objects

Scopes

  • 3 Scope rule
    • names are either local or global or built ins
  • Local names defined by assignment unless ‘global’ definition says otherwise
    • local means existing in current class, function, global means existing in current module and not existing everywhere
    • builtins is just a special namespace used by builtin functions
    • if you have a global of the same name as a builtin the compiler will find the global instead of the builtin

Modules

  • They have their own namespace, keeps the rest of the modules tidy
  • Executed on first import, namespace becomes attributes
  • Then cached in sys.modules
  • import is syntactic sugar, it calls in the following function
    • mod = __import__(“mod”)
  • sys.modules doesn’t have to contain only modules
    • it is just a mapping of names to whatever object you want import to return
  • If you map None to a name then it will raise import error

Python Design

I will add a series of these posts which are just a bunch of notes that I am going to create for learning Python in depth from one of the Google talks on Python.

  • Everything is run time* (compile time* too is runtime)
    • somethings are cached (.pyc files)
  • Execution happens in namespace
    • modules, functions and classes all have their own namespace.
  • Modules are executed top to bottom
    • just like a script
  • def and class statements are runtime

Function creation

  • def statement creates a function
  • Code is compiled at compile time
    • into a code object
    • The code for the function will be compiled into a code object, which is a separate object from whatever code the rest of the program is compiled into
  • Wrapped in a function object at def time
    • When the def statement is executed the code object is wrapped into a function object along with whatever arguments it takes and any defaults to those arguments
  • Arguments defaults evaluated then too
  • def is primarily an assignment statement
    • essentially if you look at the bytecode then it is the same bytecode as the assignment operation

def func(arg1, arg2=func2()):
    print "entering func1"
    def inner_func(arg3=arg2):
        print "entering inner_func"
        return arg1, arg3
    arg1 = arg2 = None
    return inner_func

When the def statement is reached that whole line gets evaluated including the default arguments and the rest of the program which is


    print "entering func1"
    def inner_func(arg3=arg2):
        print "entering inner_func"
        return arg1, arg3
    arg1 = arg2 = None
    return inner_func

has been compiled because the compile time is in the past but is not being executed until you call the function. When func() is executed the inner func is evaluated till the def statement along with the defaults but the rest is compiled and also the defaults are evaluated at this time so whatever arg2 was is assigned to arg3 and not arg3 will not get that value of arg2 when you call inner_func so if the value of arg2 changes later on the value of arg3 will still be that value of arg2 when the def statement was reached.

 

Class Creation

Pretty similar to functions but a little different as well

  • Class statements executes suite
    • in a separate namespace
    • Class statement is followed by a block of code that is executed when the class statement is reached.
  • Class object is created out of the dict
    • name space becomes attribute space
  • Methods are just functions inside a class
    • Special wrappings happens automatically at attribute level
    • self is passed implicitly but received explicitly
  • Class body is normal code block.

* There is a pretty clear answer on stackoverflow regarding this concept which I would like to add here.

Run time and compile time are different stages in the running of a computer program. It is quite a difficult concept to learn and it is best approachable if you ask it in terms of these questions.

  1. What invariants the program satisfy.
  2. What can go wrong in this phase.
  3. If the phase succeeds what are the post conditions.
  4. What are inputs and outputs if any.

Compile time

  1. The program need not satisfy any invariant, in fact it need not be well formed at all.
  2. Things that can go wrong here are
    1. Syntax errors
    2. Type checking errors
    3. Compiler crashes
  3. If the compiler succeeds we know that the program is well formed and it is possible to run the program.
  4. Inputs and Outputs?
    1. Inputs are the program itself along with the headers or any other libraries to be imported
    2. Output is the assembly code or relocatable object code or executable. If the program has errors then outputs are the bunch of those error messages.

Run time

  1. We know nothing of program invariants, they can be anything that the programmer specifies
  2. Things that can go wrong here are
    1. Division by zero
    2. Dereferencing a null pointer
    3. opening a file which is not already there
  3. If run time succeeds the program finished without crashing
  4. Inputs and outputs are entirely on the programmer.