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
- 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.
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.
- What invariants the program satisfy.
- What can go wrong in this phase.
- If the phase succeeds what are the post conditions.
- What are inputs and outputs if any.
- The program need not satisfy any invariant, in fact it need not be well formed at all.
- Things that can go wrong here are
- Syntax errors
- Type checking errors
- Compiler crashes
- If the compiler succeeds we know that the program is well formed and it is possible to run the program.
- Inputs and Outputs?
- Inputs are the program itself along with the headers or any other libraries to be imported
- 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.
- We know nothing of program invariants, they can be anything that the programmer specifies
- Things that can go wrong here are
- Division by zero
- Dereferencing a null pointer
- opening a file which is not already there
- If run time succeeds the program finished without crashing
- Inputs and outputs are entirely on the programmer.