formations/python/python3/en/introspection.txt

233 lines
5.5 KiB
Plaintext

Instrospection
==============
Python's introspection capabilites. First, we shall use the prompt.
The prompt
-----------
Type `python3` in the prompt. It gives you a prompt, which is the python prompt::
>>>
The prompt enables us to deeply analyse the fundamentals of the language.
It is interesting for a good understanding of the concepts.
For example, **introspection**. Introspection means finding informations
about each element you want to manipulate::
>>> locals()
{'__name__': '__main__', '__package__': None, '__doc__': None,
'__builtins__': <module 'builtins' (built-in)>, (...) }
>>>
.. glossary::
locals
The `locals()` builtin function lists the variables that lives in the
current namespace.
globals
The `globals()` builtin function lists the variables that lives in the
general namespace.
`locals()` in the global namespace and `locals()`` in a local namespace
(a function's namespace)::
>>> def myfunc(x):
... a = 2
... print(locals())
...
>>> locals()
{'__package__': None, '__spec__': None, (...)'__name__': '__main__', '__builtins__': <module 'builtins' (built-in)>}
>>> # we can see that there's no "a" variable
>>> myfunc("toto")
{'x': 'toto', 'a': 2}
>>> # in the function there is a "a" variable
When we open a prompt, the general namespace and the local namespace are the same.
.. glossary::
builtins
The `__builtins__`` module is a special module :
it is the only namespace which is automaticaly imported.
It means that the variables function that are in the builtins are always
accessible. You can always call them.
For example, you can use the function `dir` which is directly accessible
without importing any module::
>>> dir()
['__builtins__', '__cached__', '__doc__', '__loader__', '__name__', ...]
>>>
In fact, the `dir()` function lives in the `__builtins__`::
>>> __builtins__.dir()
['__builtins__', '__cached__', '__doc__', '__loader__', '__name__', ...]
type::
>>> help(dir)
to have help on a given function or module.
`__doc__`: this namespace's docstring
`__package__`: the current namespace
`__name__` is the name of the current namespace, which is `__main__`::
>>> __name__
'__main__'
>>>
why is it `__main__` ? Because we are located in the global namespace.
Modules
-------
A module is a namespace, it is a pyhton file that you can import in another module.
A python file is intended to become a library, but you can use it as a script.
If you want to use module as a script, the good pratice is to fix its behavior with::
if __name__ == '__main__':
do_this()
It means that if you launch the module in the global namespace, then the module
is not used as a library but as a standalone script.
The good practice in a module is to do nothing.
If you launch::
do_this()
without the test condition::
if __name__ == '__main__':
when you import the module::
import mymodule
it will launch the `do_this` function, wich is not a intended behavior for a library.
A library is just a set of function/classes that are available in a given namespace.
A script is intended to do something when launched, not a library.
What are scripts ?
Scripts are executable file, they have a she bang::
#!/usr/bin/env python3
You can import some other libraries in your script, and it becomes an application::
import my_second_module
or::
from my_second_module import my_function
or::
from my_second_module import my_function as my_function_alias
or::
import my_second_module as my_second_module_alias
Assinging a variable
---------------------
::
>>> a = 42.
>>> type(a)
<class 'float'>
what is dynamic typing ? You can set some other value to the `a` variable that
has nothing to do with the previous type::
>>> a = 42j
>>> type(a)
<class 'complex'>
>>>
Functions
----------
This function::
>>> def my_function(a, b):
... """this is my func docstring"""
...
is equivalent to::
>>> def my_function(a, b):
... """this is my func docstring"""
... return None
There are no procedures in python (a procedure returns nothing). It means that
a function return always someting. Even if you don't *return* something: it
returns `None`, which is something::
>>> result = my_function(1, 2)
>>> print(result)
None
>>> print(my_function(1, 2))
None
**In python, a function is... an object**. Yes. What is a docstring's function
? A Docstring is the `__doc__` attribute of the `my_function` object::
>>> my_function.__doc__
'this is my func docstring'
>>>
In python, absolutely everything is an object... even the functions::
>>> type (my_function)
<class 'function'>
>>>
A function is an instance of the `function` class.
Unnamed arguments in a function::
>>> def my_fonction(*args, **kwargs):
... print("arguments : ", str(args))
... print("named argumments : ", str(kwargs))
...
>>> my_fonction("toto", "titi", tutu=2, tata=3)
arguments : ('toto', 'titi')
named argumments : {'tata': 3, 'tutu': 2}
>>>
The *samouraï* rule
~~~~~~~~~~~~~~~~~~~~
A function shall return the expected result, or... kill itself
(that is, raise and exception).
>>> def function_raise(x):
... if not type(x) == int:
... raise TypeError("Not the right type")
... else:
... return x + 1
...
>>> try:
... e = function_raise("une string")
... except TypeError, e:
... print e
...
Not the right type
>>