You are on page 1of 26

PYTHON LANGUAGE SUMMARY

Everything in Python is an Object.


Objects are Garbage-Collected
Pickle Example
o
D = {'a': 1, 'b': 2}
>>> F = open('datafile.pkl', 'wb')
>>> import pickle
>>> pickle.dump(D, F) # Pickle any object to file
>>> F.close()
Shelves save object by key. Shelf example:

Python is a first-class object model: Everything is an object. For ex function


objects may be assigned to other names, passed to other functions, returned from
other functions, etc. One can attach arbitrary new attributes to any object.
Ex:
Def f(): pass is an blank function object.
I could add f.a = 2 and it would be legal!
Python standard library glob allows to get directory listings in Python code.

DATA TYPES
-

Immutable Data Types Cannot be changed in place Strings, Numbers, and


Tuples
Mutable data types Lists, Dictionaries, and Sets, (classes and instances too)
Shared references can be a problem or asser for mutable data types because
copies are not generated by default.
dir(S) Generates a list of all type attributes
help(S) Also gives documentation
(map(func,L)) # map applies the function func to all elements of L and returns an
iterable
Sorted(x) In-built function for sorting data
Sequences A positionally ordered collection of other objects. Strings, Lists, and
Tuples
Type(L) - Returns the type
Isinstance(object,type) Check if object is of type
== operator tests value equivalence
is operator tests identity

STRINGS
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o

S = Len(test) # Length of string


S*3
# Repeat S 3 times.
S[0]
# zero-based position
S[-n]
# n-from-last item
S[1:n]
# Slicing Does not include nth item.
S[:]
# Everything
S[:-1]
# All but last
S+S
# Concatenation
L = list(S)
# Expand into a list
-.join(L)
# Join elements in list L with - separator
S.find(es)
# Find offset of a substring in S
S.replace(es,ro)
S.split(,)
# Splits the string at ,
S.rstrip
# remove right-hand side whitespace characters
S.isdigit()
S.lower()
# case conversion
S.encode
# Unicode formatting
S.decode
# Unicode decoding
Single quotes: 'spa"m'
Double quotes: "spa'm"

o
o
o
o
o

Triple quotes: '''... spam ...''', """... spam ..."""


# Block comments
Escape sequences: "s\tp\na\0m"
myfile = open(r'C:\new\text.dat', 'w')
# r indicates raw string. It
suppresses escapes
'%(qty)d more %(food)s' % {'qty': 1, 'food': 'spam'}
# Dictionary
based formatting
Formatting Methods

template = '{motto}, {pork} and {food}' # By keyword

template.format(motto='spam', pork='ham', food='eggs')


'spam, ham and eggs'

LISTS
o

o
o
o
o
o
o
o
o

Unpacking a list:
x = ([[1,2,3,4,5,6,7],[8,9,10,11,12,13,14]])
a,b = x
a is the first row, b is the second row
Similar to strings for slicing, length, etc
L.append(xyz)
L.pop(2)
# Deleted element at position 2, default value -1
L.extend([3,4,5])
List(reversed(L))
L.remove(spam)
# remove by value
L.count()
Del L[0]
# Delete one item

COMPREHENSIONS
o

[x**2 for x in M if x %2 == 0]
M is an iterable

DICTIONARIES
o
o
o
o

o
o
o
o
o
o
o
o
o
o
o
o
o
o

Sequence operations do not work


Assigning to new indices adds entries
Keys can be anything, not just strings
Initialization
D = {food:banana,vehicle:car}
D = dict(food = banana, vehicle=car)
D = dict(zip([food,vehicle],[banana,car]))
D[food]
# to index banana
Can nest data types Lists of dictionaries. Dictionary with lists indexed by
strings. Any order is legal
food in D
# Searching with key
D.keys()
# lists all keys
D.sort()
# Sort all keys
D = dict.fromkeys(['name', 'age'])
D.items()
D.copy()
# Copy top-level
D.clear()
# Remove all items
D.get(key, default?) # fetch by key, f absent default
D.pop(key, default)
Len(D)
Del D[key]
D.viewkeys(), D.viewvalues()

D = {x:x*2 for x in range(10)}

# Dictionary comprehension

o
o

For x in spam:
While (x>0)

o
o
o
o
o
o
o
o
o
o
o
o
o

Ordered collection of arbitrary objects


Accessed by offset
Immutable Sequence
Fixed length, heterogeneous and arbitrarily nestable
They are basically arrays of object references
Comma separated expressions results in tuples
Tuple(L) Create a tuple from another sequence type.
T = (1,2,3,4)
Len(T)
T + (5,6)
# Concatenation
(1,2) * 4
# Repetition
T.index(4)
# Gives index of the entry whose value is 4
T.count(4)
# Count occurrences of 4

o
o
o
o
o
o
o
o
o

File iterators are best for reading lines


Content is string, not objects
Files are buffered and seekable
Close is often optiona: auto-close on collection
output = open(r'C:\spam', 'w')
# Create output file ('w' means write)
input = open('data', 'r')
# Create input file ('r' means read)
input = open('data')
# Same as prior line ('r' is the default)
aString = input.read()
# Read entire file into a single string
aString = input.read(N)
# Read up to next N characters (or
bytes) into a string
aString = input.readline()
# Read next line (including \n newline) into a
string
aList = input.readlines()
# Read entire file into list of line strings
(with \n)
output.write(aString)
# Write a string of characters (or
bytes) into file
output.writelines(aList)
# Write all line strings in a list into file
output.close()
# Manual close (done for you when file
is collected)
output.flush()
# Flush output buffer to disk without closing
anyFile.seek(N)
# Change file position to offset N for
next operation
for line in open('data'):
# use line File iterators read line by
line
open('f.txt', encoding='latin-1')
# Python 3.X Unicode text files (str
strings)
open('f.bin', 'rb')
# Python 3.X bytes files (bytes strings)
codecs.open('f.txt', encoding='utf8')
# Python 2.X Unicode text files
(unicode strings)

LOOPS

TUPLES

FILES

o
o
o
o
o
o
o
o
o
o
o

open('f.bin', 'rb')

# Python 2.X bytes files (str strings)

o
o

Can only contain immutable data types


Sets do not have duplicates
L = [1,1,2,3]
Set(L) # gives {1,2,3}
List(set(L)) # gives [1,2,3]
X = set{spam}
X = {s,p,a,m} # Both are equivalent
X&Y
# Intersection
X|Y
# Union
XY
# difference in element membership
X>Y
# superset test
{n ** 2 for n in [1, 2, 3, 4]} # Set comprehensions
list(set([1, 2, 1, 3, 1])) # Remove duplicates (Maybe reordered)
[1, 2, 3]
set('spam') - set('ham') # difference in collections
{'p', 's'}
set('spam') == set('asmp') # Order-neutral equality test
True

SETS

o
o
o
o
o
o
o
o
o
o

OPERATORS
-

X/Y Classic or true division


X//Y Floor division
Python supports complex numbers as well
o -2j + 1
Enumerate() returns an iterator. Can make certain loops a bit clearer.
enumerate(thing), where thing is either an iterator or a sequence, returns a
iterator that will return (0, thing[0]), (1, thing[1]), (2, thing[2]), and so forth.

STATEMENTS
-

Range(10) generates an iterable.


Zip creates tupes
Map creates dictionaries
Enumerate() generates a generator object

There is a loop else construct where the else is hit if there was no break:

ITERATION PROTOCOL

Any object with a __next__ method supports iteration protocol. It automatically advances
for each call. An iterable object is created by __iter__ call. __next__ raises StopIteration at
the end of the series of results.
Old way to read a file consumes too much memory:

forlineopen(' script2. py '):Use fileiteratorsreadby lines


print(line.upper (),end='')Calls next ,catchesStopIteration
Iterator based method is more memory efficient:

f =open(' script2. py')

whileTrue:
...line=f .readline()

...if notline:break
... print(line.upper(),end='')
In-built functions:

object with a

next

iternext

call

next
ite r

respectively.

Iter

call creates an

function implemented in it. A file object is its own iterator. SO it is

not necessary to create an iterator for it. For lists, it is necessary to create an iterable
because they support multiple open iterations. Objects that are iterable return the
results one at a time and not all at once in a physical list.

ITERABLE OBJECTS:
1.
2.
3.
4.

Dictionaries (in 3.x)


Shelves
Files
List

LIST COMPREHENSIONS (SIMILAR TECHNIQUE FOR SET AND DICTIONARY


COMPREHENSIONS)

1.

f = open('script2.py')
lines = f.readlines()
Lines is a list = ['import sys\n', 'print(sys.path)\n', 'x = 2\n', 'print(x ** 32)\n']
2. Can use a conditional if
lines = [line.rstrip() for line in open('script2.py') if line[0] == 'p']
3. Can use nested for
[x + y for x in 'abc' for y in 'lmn']

OTHER ITERATION CONTEXTS


1. Map returns an iterable object
2. The inbuilt function

list

3. Tools such as

sorted
and

uses an iteration protocol.

tuple

. Even the string

join

method uses an

iteration protocol.
4. Set and Dictionary comprehensions support the extended syntax of list
comprehensions.
5.

Range(x)

6.

map,zip,filter

7.

range

returns an iterable in 3.x.


also return an iterable in 3.x.

is not its own iterator. It has to be created.

DOCUMENTATION
1. Dir returns list of all attributes in an object.
2. __doc__ - Comments coded at the top of modules, function, class statements etc
are automatically stuffed into the

attribute and are called

docstrings

FUNCTIONS
1.
2.
3.
4.
5.

Def is an executable code.


Def creates an object and assigns it a name.
Lambda creates an object but returns it as a result.
Return sends a result object back to the caller.
Yield sends a result object back to the caller, but remembers where the function
left of. Used in generators.
6. Global declares module-level variables that are to be assigned.
7. Nonlocal declares enclosing function variables that are to be assigned.
8. Arguments are passed by assignment (object reference)
9. Arguments are passed by position, unless it is passed by keywords.
10. Arguments, return values, ad variables are not declared.
11. Code inside defs not evaluated till the functions are called. Only an object is
created.

SCOPE

1. Variable assigned inside a def, is local


2. Variable assigned in an enclosing def is nonlocal to the nested function.
3. If a variable is assigned outside all the defs, it is global to the entire file.

1.
2.
3.
4.

Enclosing module is a global scope


Global scope spans a single file only.
Assigned names are local unless declared nonlocal or global.
Each call to a function creates a new local scope.

1. Name assignments create or change local names by default.


2. Name references search at most four scopes: local, then enclosing functions (if
any), then global, and then built in.
3. Names declares in global or nonlocal statements ma assigned names to enclosing
module and function scopes respectively.

FACTORY FUNCTIONS: CLOSURES


Functions can return functions!
For example:
def maker(N):
def action(X): # Make and return action
return X ** N # action retains N from enclosing scope
return action
Can also use lambda function-creation expressions:
def maker(N):
return lambda X: X ** N # lambda functions retain state too

nonlocal variables are not allowed at module level.


Note that mutable objects are passed by reference. Kind of like pointers in C.

ARGUMENTS
-

A function can return multiple values by packing them in a tuple.


Argument matching variations available o Positionals Matches from left to right.
o Keywords Match by argument name
o Defaults
o Varargs collecting arbitrarily many positional or keyword arguments
o Varargs unpacking pass arbitrarily many positional or keyword arguments
o Keyword-only arguments arguments that must be passed by name

In a function call, arguments must appear in this order: any positional arguments
(value); followed by a combination of any keyword arguments (name=value) and the
*iterable form; followed by the **dict form.
In a function header, arguments must appear in this order: any normal arguments
(name); followed by any default arguments (name=value); followed by the *name (or* in
3.X) form; followed by any name or name=value keyword-only arguments (in 3.X);
followed by the **name form.
In both the call and header, the **args form must appear last if present
The steps that Python internally carries out to match arguments before assignment can
roughly be described as follows:
1. Assign nonkeyword arguments by position.
2. Assign keyword arguments by matching names.
3. Assign extra nonkeyword arguments to *name tuple.
4. Assign extra keyword arguments to **name dictionary.
5. Assign default values to unassigned arguments in header.
We can also use a * character by itself in the arguments list to indicate that a function
does not accept a variable-length argument list but still expects all arguments following
the * to be passed as keywords.
Ex:
def kwonly(a, *b, c):
print(a, b, c)
And its usage:
>>> kwonly(1, c=3, b=2)

123
>>> kwonly(c=3, b=2, a=1)
123
>>> kwonly(1, 2, 3)
TypeError: kwonly() takes 1 positional argument but 3 were given
>>> kwonly(1)
TypeError: kwonly() missing 2 required keyword-only arguments: 'b' and 'c'

One can create function annotations:


Ex :
>>> def func(a: 'spam' = 4, b: (1, 10) = 5, c: float = 6) -> int:

return a + b + c

>>> func(1, c=10) # 1 + 5 + 10 (keywords work normally)


16
>>> func.__annotations__
{'c': <class 'float'>, 'b': (1, 10), 'a': 'spam', 'return': <class 'int'>}

LAMBDA FUNCTION-EXPRESSION
1. Lambda is an expression, not a statement
2. Lambdas body is a single expression, not a block of statements. Note that the
following is legal.
def fi():
return 2
fk = lambda x: x + fi()
print(fk(3))

3. Lambda can have defaults.


4. Lambdas can be nested too. But they should be in the same line.

MAP, FILTER AND REDUCE


-

Map apply function to all elements of an iterable.


Filter apply filter to a sequence and create an iterable that excludes the
elements that do not pass the filter
Reduce applies a function iteratively to an iterable to return a single calue.

GENERATOR FUNCTIONS
-

Coded as normal def functions but use yield instead retains state between calls.
Generator expression list list comprehensions but generates result on demand.

Generator functions
A function def statement that contains a yield statement is turned into a
generator function. When called, it returns a new generator object with automatic
retention of local scope and code position; an automatically created __iter__
method that simply returns itself; and an automatically created __next__ method
(next in 2.X) that starts the function or resumes it where it last left off, and raises
StopIteration when finished producing results.

Generator expressions
A comprehension expression enclosed in parentheses is known as a generator
expression. When run, it returns a new generator object with the same
automatically created method interface and state retention as a generator
function calls results with an __iter__ method that simply returns itself; and a
_next__ method (next in 2.X) that starts the implied loop or resumes it where it
last left off, and raises StopIteration when finished producing results.
Generators (expressions and functions) are single iteration objects.

List of all comprehension expressions:

TIMING

MODULES
1.
2.
3.
4.

Each module is a namespace


Allows for code reuse
Implements shares service or data.
Import gets the module once as an object. It does not reload it with another
import call. An explicit reload call is required. Imported modules elements have to
be accessed by the module name.
5. From xyz import abc creates a local copy of abc and does not retain the module
itself.

6. Module import procedure:

7. There locations to search is form module search path which is set by 4 parameters
Refer to documentation for more details.

8. Compiled modules saved as .pyc files.


9. Note that although from copies the values, shared values like mutables
will be affected if they are changed.
10.Copying a mutable list a list is done by L2 = L1[:]. L2 = L1 has both L2
and L1 pointing to the same object.
11. __dict__ = namespace dictionary
a. list(module2.__dict__.keys())
12.Cannot access names in another module file without importing it.
13.Module level namespace nesting follows similar rules as a single file namespace
nesting.

OOPS
-

Supports multiple inheritance and Composition


Operator overloading
Decorators
Properties
Metaclasses
Bound and Unbound Objects
New style class model.
1. Class statement creates a new class object and assigns it a name. In new-style
class a class object has the super class type.
2. Assignments inside class statements make class attributes.
3. Class attributes provide object state and behavior.
4. Class objects define default behavior.
5. Instance objects are concrete items.
6. Calling a class object like a function creates a new instance. The new instance
inherits class attributes. Unless one of the class attributes are explicitly
modified by the instance, it continues to refer to the class attributes.
For ex:
Class a:
X=1
B = a()
a.x = 2
print(b.x)

# this prints 2!

But b.x = 3;
a.x = 1
print(b.x)
# this prints 3. This is because b now has its own copy of x.
7. Assignments to attributes in self make per-instance attributes. This means that
these attributes behave like the second example in point 6 above.
8. Classes are attributes in models.
9. Classes can intercept python operators = Operator overloading.

a. Methods names with double underscores are special hooks.


b. Such methods are called automatically when instances appears in builtin operations.
c. Classes may override mose built-in type operations.
d. There are no defaults for operator overloading methods and none are
required.
e. New-style classes have some defaults, but not for common operations.
f. Operators allow classes to integrate with Pythons object model.
10. Encapsulation Wrapping up operations behind interfaces, such that an
operation is only coded once.
11. Calling superclass constructors.
a. Can use super. Keyword. Not really predictable when there are multiple
superclasses because the MRO inheritance model might change.
b. Can simply call the superclass methods by name. This is a much better
approach.
12. Inheritance

13. Abstract Superclass. In the example below action is not defined with the class
names Super. It is left to the class names sub to define it. It the function is
invoked without defining it, error results. But object creation does work. In the
following code, only b.delegate() fails.
class super:
def delegate(self):
self.action()

class sub1(super):
def action(self):
print("here")

class sub2(super): pass

a = sub1()
b = sub2()
a.delegate()
b.delegate()

14. Note that point 13 can also be done with decorators. But when done with
decorators, even instantiation fails unless all methods are defined.

NEW STYLE CLASS CHANGES


1. Attribute fetch for built-ins: instance skipped
__getattr__ and __getattribtue__ are not automatically called by built-in operations
for __X__ operator overloaded methods. The search for the name begins at classes
and not instances. Accesses by explicit names go to the instances.
2. Classes and types merged: type testing
Classes are objects of type.
Also all basic data types can now be sub-classed.
All classes derive from object.
3. Automatic object root class: defaults
4. Inheritance search order: MRO and diamonds.
5. Inheritance algorithms
6. New tools
a. Slots specifies the only attributes that can be used in a class
b. Properties Like decorators. @ property defines the get, set, delete and
doc.
Syntax attribute = property(fget, fset,fdel,doc)

The same can be coded with decorators as:

Note that when simply invokes with property key words, the attribute
becomes the fget property for the attribute. In the above example, it
becomes a property of the name attribute.
c. Descriptor Alternate way to intercept attribute access. Properties and
slots are really just a kind of descriptor.
Descriptors are coded as independent classes and provide specially names
accessor methods for tha attribute access operations that they wish to
intercept.
Get, set and deletion methods in the descriptor class are automatically tun
when the attribute assigned to the descriptor class instance is accessed.
Note that all get, set and deletion methods need not be specified. Presence
of any one makes it a descriptor.

A better example:

d. Super like super in systemverilog.


e. __getattribute__ method

OPERATOR OVERLOADING

1.
2.
3.
4.
5.
6.
7.

__init__ - Constructor function


__bases__ - Lists all the superclasses.
instance.__class__.__name__ = Outputs name of the class ofinstance
instance.__dict__.keys()
__getattr__ = called when asking for undefined attributes
__setattr = called when setting all attribtues
__getattribute__ = calling when asking for any attributes

NAME MANGLING
If attributes are prefixed by two underscores, python automatically prefixes it with the
class name. This is useful when we want the variable names to be class_specific. __X
becomes __C__X

BOUND AND UNBOUND METHODS


UNBOUND (CLASS) METHOD OBJECTS: NO SELF
Accessing a function attribute of a class by qualifying the class returns an unbound
method object. To call the method, you must provide an instance object explicitly as the
first argument. In Python 3.X, an unbound method is the same as a simple function and
can be called through the classs name; in 2.X its a distinct type and cannot be called
without providing an instance.

BOUND (INSTANCE) METHOD OBJECTS: SELF + FUNCTION PAIRS


Accessing a function attribute of a class by qualifying an instance returns a bound
method object. Python automatically packages the instance with the function in the
bound method object, so you dont need to pass an instance to call the method.

FUNCTION DECORATORS
A decorator is a callable that returns a callable. A decorator can be any type of callable
that returns a callable. Note that classes, functions, generators can return items.
Decorators also support nesting.

Example for Nesting:

Ex :
def propmethod(func):
print("here")

return func

class super:
@propmethod
def delegate(self,a):
print("here,%d",a)

a = super()
a.delegate(3)

CLASS DECORATORS
This is similar to function decorators but manages instances created from the class.

The following is legal too!:

The same functionality can be implemented using functions. Note that when defined,
decorators create an object. When the object is subsequently called, the new properties
are applied.

You might also like