DocumentVersioning
Last update: 01 AUG 2022
Content
Content is organized more like a bag of various things. An excellent book on the subject of this programming language is the book from the author of this programming language Gvinno Van Rossum, which is nowadays converted into a tutorial [8].
Let's start.
# 0 . sha-bang
#!/usr/bin/env python3 - This is a sha-bang for python3.
Sha-bang has a long history for Unix/Linux OS-es, but for Windows, in fact it's possible to use it as well.
py.exe - python launcher with a choice of interpreter of sha-bang under Windows
python -c "import this" - looking at the world from the point of view of python
An object in python terminology is both class instances and exotic objects such as files and integers.
In Python, everything that takes up memory in some form is called an object.
# 1. Check that objects refer to the same data.
In Python 2. * actually meant the address of an object in the interpreter's memory.
If you need to compare references to an object, then an action can be performed also via using operators: is, is not.
id(x) == id(y) x is y
# 2. There are only references to objects
Python has named reference to objects, and as such has no variables available to the programmer for reference by value. Functions return and accept arguments by reference.
Moreover - for default arguments, the default value itself is passed by reference and calculated once. This creates an implicit global default value object. For C++ this is not observed, because arguments are passed by value, in the usual way of writing arguments, and is just a shorthand.
How to get around over that to not hurt the "default value" object:
def f(arg=None) : if (arg == None): arg = []
# 3. Object equality
Value equality is testing with reference to objects with the same content, the programmer can define what this means via define __eq__ operator which is the same as ==
Identity is a reference to the same object. The programmer can not determine what it means, it is defined by the language. Such type of equality is using during use of operators is or id.
# 4. About scripting languages in general
Ruby, Python - dynamic & strong type system. This means that types are inferred at runtime (dynamic), but implicit conversions between types are not allowed (strong)
Js, Perl - dynamic & weak type system
C++ - static and strong type system.
# 5. Namespaces for name lookups. (context in python terminology)
5.1. Inside the current function. A new loop with a new indentation does not introduce new local scope ( Local )
5.2. Locally declare a function inside a function. Variables from the parent function will be implicitly accessible ( Enclosing )
def f (): def g (): print y y = 90 g() y = 100 g()
5.3. Variables from the top level of the module (Global)
5.4. Variables from the built-in (Built-in) module
# 6. About objects
In Python, everything is an object. The dir() built-in function displays the attributes of an object. Attributes that all objects have
__name__ - name
__doc__ - documentation
__class__ - type name
def qhello ( a ) : "" "TEST FUNC. Args: a: nothing Returns: nothing" "" print (123)help(qhello)
# 7 . Printing. The need for parentheses around print appeared in python3. Also, there is a style about printing with a C # -style string format.
print ("Hello {0} / {0}".format(a));print ("Hello {arg} / {arg}".format(arg = 12));print ("Hello {1} / {0}".format(12,14));print (__ name__) # Prints the name of the current moduleprint ("%s - %i"% ('hello', 123)) # Python print style
List of supported string formats - https://docs.python.org/2/library/stdtypes.html#string-formatting, https://docs.python.org/3.4/library/string.html#formatspec
Also in Python 3 since version 3.6 there was a string interpolation feature, which exists in Bash and similar scripting languages: https://www.python.org/dev/peps/pep-0498/
a = 123print (f"Hello {a}");
And even more than that, you can specify any Python expression in {} since f-strings are evaluated during script execution, although in terms of type they are just str.
#8 . Built-in container types in python
tuple, list, str, dict, set, range (also in python2), bytes (python 3)
- They all support in, not in ( container protocol ) operators. For your types, you should define __contains __ (self, item) Example: if (x in someList)
- They all support len (x) ( sized protocol ) operators. For your types, you should define __len __ (self)
- They all support the iter(x) operators. Such objects can be used in for-loops ( iterable protocol) for i in iterable: smth (i) for your types you should define __iter __ (self) , __next __ (self)
More details: https://docs.python.org/3/tutorial/classes.html#iterators
- All of them except dict support indexing ( sequence protocol )
x [integral_index] x.index (someValue) x.count (someValue) produceReverseSeq = reversed (x)
For your types you should define __getitem__, __setitem__, __delitem__
# 9. Working with built-in types
a = (12,) # To create a tuple from one element requires some syntactic tricks a = () # Сreate an empty tupletuple([1,2,23]) #create tuple from list
Tuple packing, unpacking is an interesting idea at the language level.
https://docs.python.org/3/tutorial/controlflow.html#unpacking-argument-lists
for i in reversed ([1,3]): print i # reverse any sequence, getting an iterator emptyDictinoary = {} # dict can be built through {}, as well as through dict (list of pair-tuples with key and value) # dict can be merged with another dict via update () aSet = {1,2}; # set. You can perform set-theoretic operations on it emptySet = set() # creating an empty seta, possible only through the constructor because {} is reserved as an empty dictionary description
# 10. Exceptions with variable names
def hello(a): try : raise ValueError ( ) return +2 except (ValueError, TypeError) as e : return -1 finally: #clean code pass
# 11. Generators
Generator object "as like as" retrieve iter (some container). Extra info about yield statement: https://docs.python.org/3/tutorial/classes.html#generators
def gen(): print ("Entry point in gen") # this will be execute only ones, even function yeild several values yield 1 # emit value yield 2 # emit one more value a = gen ()
next ( a ) # use it to explicitly first yeild statement
next (a) # run to second yeild statement, etc. Last yeild will throw StopIteration exception
# 12 Comprehensions syntax
[expr(item) for item in iterable if condition (item)] # list comprehensions in python{expr(item) for item in iterable if condition (item)} # set comprehensions in python{someKey:someValue for someKey, someValue in someDict.items() if condition(someKey, someValue)} # Dictinory comprehensions in python with filtering(expr(item) for item in iterable if condition (item)) # Generator comprehensions in python
# 13. We can assume that in python the methods of all classes are virtual.
But actually, there are no virtual methods and virtual function tables in Python at all.
Methods are attributes, and they are bound at runtime and executed dynamically. There is also no division of fields into public/private/protected.
# 14 Files
# used default encoding for text files import sys sys.getdefaultencoding ( )
# file is the iterable returned for text files - line by line
f = open() f.close()
# <= equal to => with open(...) as f: smth#end of block with implicit close
# 15 Python benefits
0. Supports multiple inheritance, exceptions, "virtual" method logic
1. More correct code from a style point of view
2. Python supports limited support for private attributes objects when naming attributes as __attributename. This attribute is replaced by the interpreter with the _classname__attribute.
3. Automatic cross-platform serialization "pickling" for the user and built-in types from python std lib
4. A lot of free and commercial IDE with intel-science and etc
5. Python use "." to separate packages/subpackage/class like C#, Java. Packages from Perl are called modules in Python.
6. In Python and in Perl there is not exist such term as function overloading
7. Python has a built-in debugger. For example, using text commands, you can make sure that the parsing of the function is performed only at the moment of the direct call.
>>> import statement pdb >>> pdb.set_trace()
sys.path - the names of the directories in which to look for modules during import. Values from the environment variable PYTHONPATH are added to it when the interpreter is initialized.
#16 The following expressions are considered false in Python (Python, Rossum, 10.2.5)
None, 0, empty sequence, len () == 0
# 17 Generally compound statements are written on multiple logical lines using indentation,
although if a compound statement has only one branch, the body of which contains only simple statements, it can be written on a single logical line. Python, Rossum, 10.4
if 1: print (2); print (2); #legal
https://docs.python.org/2/reference/simple_stmts.html
"Simple statements are comprised of a single logical line. Several simple statements may occur on a single line separated by semicolons."
Python statements are usually written in a single line. The newline character marks the end of the statement.
If the statement is very long, we can explicitly divide it into multiple lines with the line continuation character (\).
Python supports multi-line continuation inside:
- parentheses ()
- brackets []
- and braces {} .
The brackets are used by List and the braces are used by dictionary objects. We can use parentheses for expressions, tuples, and strings.
# 18 For efficiency reasons, each module is only imported once per interpreter session.
Therefore, if you change your modules, you must restart the interpreter - or if it's just one module you want to test interactively, use reload () , eg
import imp; imp.reload (module name).
# 19 If you launch fibo.py with python fibo.py then the code in the module will be executed, just as if you imported it, but with the __name__ will be set to "__main__".
So with the construction “if __name__ == " __main__ " -- you can make the file usable as a script too.
# 20 Search strategy to find modules
1. A built-in modules
2. Search in “sys.path”, after launch interpreter it contains
a. The directory containing the input script (or the current directory)
b. PYTHONPATH
c. Installation-dependent default
# 21 Relative imports. Relative imports are based on the name of the current module
from . import echo #A single dot means that the module or package referenced is in the same directory as the current location.
from .. import formats # Two dots mean that it is in the parent directory of the current location—that is, the directory above.
# 22 Underscore Variable
# 23
https://stackoverflow.com/questions/2965271/forced-naming-of-parameters-in-python/14298976#14298976
https://docs.python.org/3/reference/compound_stmts.html#function-definitions
Parameters after “*” or “* identifier” are keyword-only parameters and may only be passed via using keyword syntax.
>>> def foo(pos, *, forcenamed):... print(pos, forcenamed)... >>> foo(pos=10, forcenamed=20)10 20
# 24
"When a final formal parameter of the form ** name is present, it receives a dictionary (see types mapping) containing all keyword arguments,
except for those corresponding to a formal parameter.
This may be combined with a formal parameter of the form * name which receives a tuple containing the positional arguments beyond the formal parameter list.
(* name must occur before ** name.).
For example, we can define a function like this:
def cheeseshop (kind, *arguments, **keywords):
pass
# 25 Assignments do not copy data - they just bind names to objects
# 26 The comma at the end of print leads to the insertion of space, no newline is inserted in this case (Python 2). In python 3: print("hello",end='!')
# 27 __varname for a class makes it inaccessible outside the class directly, its name is replaced by the interpreter as "_class__attribute" and furthermore not available for Intelisense.
It is possible to get through to these attributes inside the class, but from the outside it is problematic, it's possible only via workaround syntax.
# 28
Calling a function with passing a tuple and dictionary. You can:
- Expand list and tuple with *
- Expand the dictionary (dict) with **
def printInfo (*x, **kv):
print len (x)
print len (kv.keys ())
x = (1,2) printInfo(*x, a = 1, b = 9, c = 1)
# 30
Simple instructions can be written in one line
# 31
Printing to stderr import sys; print >> sys.stderr, "qwe"
# 32
sym = '0' if 1> 5 else ''1"
https://docs.python.org/2/reference/expressions.html#conditional-expressions
# 33
The result of the expression 12 or 2 is 12.
In Python, when using logical connectives, the result of a compound expression is equal to the result of the last subexpression evaluated.
This is almost the same as the logical operators ||, && in C ++. The point is that in C / C ++ the result of a Boolean expression is always an integer 0 or 1 .
# 34
About some parts of collections - collections.defaultdict
https://docs.python.org/3/library/collections.html#collections.defaultdict
"... Defaultdict is a subclass (derived class) of the built-in dict class .... Each key is encountered for the first time, it is not already in the mapping ... So an entry is automatically created using the default_factory function ... "
# 35
It is recommended to use spaces instead of tabs in Python code in accordance with this recommendation
https://www.python.org/dev/peps/pep-0008/#tabs-or-spaces
# 36
Function Attributes
# https://stackoverflow.com/questions/5478351/python-time-measure-function#!/usr/bin/env python3import time def timing (f): def wrap (* args): time1 = time.time () ret = f (*args) time2 = time.time () print ('{: s} function took {: .3f} ms'.format (f .__ name__, (time2-time1) * 1000.0)) return ret return wrap # Use Attributes@timing def f1 (): time.sleep (3) # Similar code without attributesdef f2 (): time.sleep (3) f3 = timing (f2) f3 ()
# 37
Type Hints
https://docs.python.org/3/library/typing.html
# 38 Variable Introspection
dir() will give you the list of in-scope variables
globals() will give you a dictionary of global variables
locals() will give you a dictionary of local variables
# 39 Python Package Index repository
https://pypi.python.org/pypi - standard packages repository
https://pip.readthedocs.org/en/stable/ - document how to use pip
Some simple commands
pip install | uninstall package_name
pip list
pip search package_name
pip install -U package_name
# 40
The terminology of Python classes in terms of C++
In C++ terminology Python classes have the following characteristics:
1. Normal class members (including the data members) are public (except some small support for Private Variables)
2. All member functions/methods are virtual.
3. Like in C ++, most built-in operators with special syntax (arithmetic operators, etc.) can be redefined for class instances.
4. Python Data attributes correspond to “data members” in C ++.
# 41
The key difference with C ++
Assignments do not copy data - they just bind names to objects.
In Python class data attributes override method attributes with the same name;
To avoid accidental name conflicts, which may cause hard-to-find bugs in large programs, it is wise to use some kind of convention that minimizes the chance of conflicts
In fact, nothing in Python makes it possible to enforce data hiding - it is all based upon convention.
# 42
nonlocal variables scope changed the scope to the outer function.
global variable scope changed immediately to the module-level binding without any intermediate outer scope, relative to current internal.
https://stackoverflow.com/questions/1261875/python-nonlocal-statement
# 43
super () is a built-in function
super () let you avoid referring to the base class explicitly, which can be nice sometimes.
https://docs.python.org/3/library/functions.html#super
https://docs.python.org/2/library/functions.html#super
# 44
Special / Magic method for classes
https://docs.python.org/3/reference/datamodel.html#special-method-names
# 45
Function and Type annotations:
Type annotation: https://docs.python.org/3/library/typing.html
Function annotations: https://docs.python.org/3/tutorial/controlflow.html#function-annotations
Function annotations are completely optional metadata information about the types used by user-defined functions (see PEP 3107 and PEP 484 for more information).
Annotations are stored in the __annotations__ the attribute of the function as a dictionary and have no effect on any other part of the function.
Parameter annotations are defined by a colon after the parameter name, followed by an expression evaluating the value of the annotation (typically this is an expression with type information).
Return annotations are defined by a literal -> followed by an expression:
>>> def f ( ham : str , eggs : str = 'eggs' ) -> str : return "1"print ( "Annotations:" , f . __annotations__ )
By experiments, we can add types and values into the annotation. Decoration: https://book.pythontips.com/en/latest/decorators.html
# 46 Some code snippets
- Numpy usage
a = np.array ([[1,2,3], [4,5,6]])
b = a [...]
The ellipsis is used in NumPy to slice higher-dimensional data structures.
It's designed to mean at this point, insert as many full slices (:) to extend the multi-dimensional slice to all dimensions.
b = a [..., np.newaxis]
Simply put, the new axis is used to increase the dimension of the existing array by one more dimension, when used once. Thus,
- Show image with Matplotlib
import sys import matplotlib.pyplot as plt import numpy as np img = np.random.randint(low = 0, high = 255, size = (16 , 16, 3)) plt.imshow(img) plt.show()
- Show Graphic (simple)
import matplotlib.pyplot as plt import numpy as npimport matplotlib.pyplot as plt x = np.arange ( 0 , 10 , 0.1 ) y = np.sin ( x ) plt.plot ( x , y ) plt.grid ( True ) plt.show ( )
- Show sub-images
import sys import matplotlib.pyplot as plt import numpy as np out_arr = np.random.randint ( low = 0 , high = 255 , size = ( 16 , 16 , 3 ) ) plt.figure (figsize = (15 , 15)) for n in range ( 16 ) : ax = plt.subplot ( 4 , 5 , n + 1 ) ax.title.set_text ( 'Plot #' + str ( n + 1 ) ) plt.imshow ( out_arr ) plt.axis ( 'off' ) plt.subplots_adjust ( wspace = 0.01 , hspace = 0.1 ) plt.show ( )
- Show subimages
fig , ax = plt.subplots ( 1 , 3 ) ax [ 0 ].imshow ( examples [ 0 ] ) ax [ 1 ].imshow ( examples [ 1 ] ) ax [ 2 ].imshow ( examples [ 2 ] )