46
Introduction to Python Basics

Introduction to Python Basics. Hello World print “Hello World!” #2.x print(“Hello World!”) #3.x # comments start with # # final ; is optional (and rare)

Embed Size (px)

Citation preview

Introduction to Python

Basics

Hello Worldprint “Hello World!” #2.xprint(“Hello World!”) #3.x# comments start with ## final ; is optional (and rare)

print “Hello”, “World!”; # spaces inserted (in 2.x, only if no space there)print(“Hello”,”World!”, sep=“ “) # this is the default separator

print “Hello World!”, # no new lineprint(“Hello World!”, end=“ “) # 3.x

print >>sys.stderr, “fatal error”print(“fatal error”, file=sys.stderr) #after import sys

Use 2to3 for automatic conversion!

Python

• Scripting Language• ~ Interpreted (compiled at first call)

– .py or .pyw .pyo or .pyc• Launch the interpreter with: “python”• Integrated development,… edit, debug:

– idle (simple, based on TKinter)• (or python /usr/lib/python2.5/idlelib/idle.py)

– eric4 (based on Qt)– pyCrust (based on wx)

• You need good cooperation between IDE and GUI lib: idle event loop will conflict with wx lib

Libraries vs programs

• Any source file can be used as a library.import mylib // for mylib.pyfrom mylib.submodule import * //nested modulesmylib.fun(0,1) //call function fun in module mylibmylib.submodule.func(1) or simply func(1)

• To know whether the current file is used as a library, or launched as a main program, one can inspect the ‘__name__’ variable.– It will have value “__main__” if in the main prg

• Example:– from PyQt4.QtCore import *– import sys– Lib path added with: sys.path.append(“/Path/dir”)

Code

• Variables:– Variables are references to values/objects– Compare values with ‘x == y’, ‘x<y’– Compare addresses with ‘x is y’, ‘x is not y’– Special object ‘None’ (unique, can be checked by ‘is’)– Types are dynamic, not declared: find with type(x)– Integers and strings are immutable

• Assigning to the variable creates a new object always

• Statements:– Delimitation based on indentation (no ‘;’ for termination)– Each statement is on a separate line– Spaces at the beginning are forbidden, or define sub-blocks (for,

if, while, etc.)

Language elements

• Functions– Subroutine, as usual– May or may not return a value (procedures)

• Methods– Function found to an object

• Operators– Common: +,-,< (assignment =, *=, +=),

(comparison ==, <=, <)– Statements: del, print– newline ending, except in sequences, (), []. {}

Keywords

• and, as, assert, break, class, continue, def, del, elif, else, except, [exec,2x] finally, for, from, global, if, import, in, is, lambda, not, or, pass, print, raise, return, try, while, with, yield

• Assignment ‘=‘ creates new reference. Need copy() for copying object!

Types• Integer: help(int), help(long), help(float), help(complex)

– bool: {True, False} or {1, 0}– int: (typical int, promoted to a long if overflow)

• n.bit_length()size bin(n) # v3.1 only• sys.maxsize (size of a native integer)

– long: (a BigInteger) #in 2.x, int=long in 3.x• 7L (is a long at compilation, or printing)• 0x7 hexa long 7 #0x7L in v2.x• 0b0111 binary 7 bin(7) # only v3.x• 0o7 octal long 7 #07L in v2.x

• / produces truncated int if both operators are int in 2.x, float in 3.x• // real division, always returns truncated

– switch behavior with: from __future__ import division # in 2.x• float

– 5.7 is actually 5.7000000000000002 #3.1 would print 5.7– Decimal (import decimal)

• X=decimal.Decimal(‘5.7’)• F=float(X)

• complex– c=1.2+3.1j

Stringshelp(str), help(bytes) #immutable v3.x help(bytearray) #mutable in 3.xhelp(str), help(unicode) # v2.x• str (byte strings): “latin 1”• unicode: u”Unicode”, u”\N{euro sign}”• binary: bytes.fromhex(‘B9 01EF’) b’\xb9\x01\xef’• rawstrings: r’\u20ac’ ->\\u20ac # verbatim strings• Convert:str.encode() strbytes; str.decode() bytesstr;

bytes(s,encoding=“UTF-8”)• Multiline strings with triple quotes: ‘’’ bla ‘’’

– Escape newline with a slash at the end– Other escapes: bell:\a, backspace:\b, formfeed:\f, verticaltab:\v, unicode:\uhhhh \

Uhhhhhhhh, octal \ooo• Cannot concatenate text and bytes• At concatenation, unicode+str returns a unicode v2.x• A character is a str of length 1

– mystring = chr(13) // a string length 1– unistr = unichr(65535) $v2.x– ord(euro) -> 8364

Strings as sequences

• S=“Therefore”• S[0],S[2],S[-2] -> ‘T’,’e’,’r’• Slicing

– S[:3] -> ‘The’ – S[-3:]->’ore’– S[1:-1:2]->’hrfr’ # sets a step of 2

• Cannot assign a char in a string! S[1]=‘w’– Rather: S[:1]+’w’+S[2:] or ‘w’.join((S[:1],S[2:]))

• Mutable string classes: cStringIO, QString– io.StringIO, io.BytesIO #v3.x

String methods

• [r]find() -> -1, [r]index() -> exception on failure• title() -> capitalize, lower(), upper(), split(x),

replace(x,y),count(x),strip(),startswith(x),isalpha• no printf() but: sys.stdout.write() or

• “The %i %s cost %f dollars” % (3, “fish”, 17.49)

• x in s -> true if x is substring of s• x not in s -> true if x is not substring of s• x + s -> concatenation• s*i -> i times concatenation of s• len(s) -> bytecount for str and chars for unicode• ‘Go {} fast by {}’.format(‘home’,’train’) // v3.1

QString for Qt

mutable, because Qt (C++) has no unicodefrom PyQt4.QtCore import *a = QString(“applet”)b = unicode(“baker”) //2.xprint a + b -> QString “appletbaker”

// Qt returns only QStrings// convert QString to unicode asap, except if the

data will only be feed back to PyQt

Collections• Immutable: tuple, frozenset

• Mutable: list, dict, set

• Tuples:– empty=() one=(1,) two=(1, 3)– three=1, 2, 3 //parentheses optional– len(three) -> 3– three[:-1] // slicing (1,2) – tuple(“Alo”) -> (‘A’,’l’,’o’)– Ex: filename.endswith((“.png”,”.jpg”))

Collections• Lists: like tuples, but mutable, created with square

brackets. Sequences/str can be automatically made lists. Copy with newlist = my_list[:].– For nested collections, use deepcopy() in the ‘copy’ module– mylist.insert(4, “element”) or mylist[4:4]=[“element”]– del mylist[4] or mylist[4:5]=[]– remove(x) # removes the leftmost occurrence of x– x in L – x not in L – L+m // concatenation or l.extend(m)– sort([key=]), pop(i), reverse(), append(x), count(x), index(x),

pop() //pops rightmost, – zip(x,y) aggregates corresponding elems in x and y; zip(*a)

unzips– (a,*rest,b) = range(5) a=0, rest=[1,2,3], b=4

More Collections• Dictionary, like HashMap:

– insects = {“Dragonfly”:500, “Beetle”:2000}– insects[“Beetle”]=200– del insects[“Beetle”] or insects.pop(“Beetle”)– vitamins=dict(B12=100, B6=250, A=38)

//only if the key is not number or keyword!– x in d, x not in d, len(d)– Methods:

• clear(), copy()->shallow copy,• keys(), values(), items() list of tuples (key,value) in 2

– views in 3.x (type->dict_keys)!» use sorted(d.keys()) instead !d.keys().sort()

• get(k,default_if_x_not_inside), setdefault(k,x_if_k_not_inside)

• update(dict(a=3)) //updates by changing/adding key/value pairs

Sets

• Like Dictionaries without values

• Like lists (created from a sequence):– unicorn = set((“Narwahl”, “Oryx”, “Eland”))– frozenset() immutable– “Goat” in unicorn– Methods: add(x), remove(x), union(t),

intersection(t), difference(t), discard(x), clear(), copy(), issubset(t), issuperset(t)

Built-insSequences:

– all(q), any(q), x [not] in q, len(q), max(q), min(q), sum(q)help(cmd), dir(x) // lists all attributes, e.g. of a modulehasattr(x,a) // x has attribute aid(x) // hashisinstance(x,C) // accounts for inheritancetype(x)eval(s)open(f,m) // open file f in mode m: “w” “r”, “wb”, “rb”, “r+b”

filehandle.read()//read entire file. filehandle.readline(read a line) //write(),seek(),close()import pickle // pickle.dump(x,file) x=pickle.load(f)

serializationrange(i) range(start,end,step) // [0..i-1], //lazy since 3.xMath: abs(n), divmod(i,j) (i/j,i%j), hex(i), oct(i), float(x),

int(x), long(x), pow(x, y[, m]), round(x,n)//n decimals

Tests

• False=0,False,None, PyQt obj with isNull()

• Check objects with bool(QDate())

if 1 <= x <= 10:

pass

If

if test:

branch 1

elif test2:

branch 2

else:

branch 3

Empty branch: “pass”

:?

Instead of test?x:y

x if test else y

and-or tricks:test and x or y # works only if bool(x)==True

(test and [x] or [y])[0]

Loops

while test:actionbreak/continue

else:branch // executed only if test fail,

// not on break

For

for var in iteratable: //xrange() for lazy eval in 2.xblockbreak/continue

else:branch

# may not change iteratable while looping# if have to change, create copy....! E.g keys()#for var in sorted(dict): //list of sorted keys# iterkeys(), itervalues(), iteritems() //2.x only: do not provide

copies and are faster... do not modify underlying dict!#iteratables have a next() and raise StopIteration exception# for key, val in dictionary:

enumerate

• enumerate(string)– returns a tuple(index, character)

• Example:

for i, char in enumerate(“10 km”):

list comprehension & generators

• List comprehension– [x for x in range(50) if x % 5 == 0]

– [(key,dictionary[key]) for key in sorted_keys]

– [ x for x in (1 , 2, 3)] # v3.x

• Generator (lazy evaluation):– (x for x in range(50) if x % 5 == 0)

• Dictionary comprehension:– {k: chr(65+k) for k in range(4)}

Functions, Methods, Lambda

# functions must be defined before usagedef funName(params):

“””docstring“””blockyield val // existence of yield make the function a generatorreturn val // without explicit return, returns None//function end without return raises StopIteration for generators

# parameter are by ref (for immutable types)# functions defined in functions are local# providing a default value: def frange(arg0, arg1=None,arg2=None) gen=frange(5,arg2=“Blah”) # positional & named gen.next() # may call next on obj returned by generator function# Lambda: // cannot contain loops, branches, or return statements cube = lambda x: pow(x, 3) # can use and-or trick (:?)# reduce applies a function of 2 parameters on a list, reducing it to a value

reduce(lambda x, y: x+y, [1,2,3,4,5]) #calculates (((((1+2)+3)+4)+5)map(lambda x, y: x+y, [1,2,3,4,5],[1,1,1,1,1]) #calculates [2,3,4,5,6]

#variable list of arguments with: def fun( *args) # -> args will be a tuple with all argumentsdef fun( * arg1, arg2) # possible in 3.x, all arguments after * must be specified with keywords

Dynamic def

import sys

if sys.version_info[:2] <(2,4):

def sorted(items):

return list(items).sort()

Partial Function Application

import functools

def myfun(a, b):

return a+b

parfun = functools.partial(myfun, 2)

parfun(3) -> 5

Exception Handling

class SimpleException(Exception): passfilehandle=Nonetry:

block // e.g. filehandle = open(“file”)if wrong: raise SimpleException, “Troubles”

except exceptions_tuple: passexcept: pass //catches any exceptionelse:

print “No exception happened!”finally:

fin // e.g.: if filehandle: filehandle.close()

#exceptions are useful to break out of deeply nested loops

Assert

• Rather than exceptions, may use assert:

def fun(a, b):assert a or b // raises AssertionError

Classes and ModulesChap 3

• support– operators– collection types (in, len())– inheritance: root is “object”– all methods are public– instances names with leading _ are private

• the names not imported with: from xxxx import *– names with _ _ are “very private” (if no ending _ _)

• the names are mangled on import:– class MyClass method _ _ method becomes: _myClass_ _method

class myclass(base_class):“”” my first class “””def __init__(self): passdef meth1(self):pass

Build Objects

methods starting & ending with _ _ are special:

__new__() allocates the object… rarely used__init__() initializes the created object__del__() called on garbage collection

Guarantee cleanup trigger with try…finallyAll methods have first parameter “self” (name can

be changed!)Create attributes as: self.attr=1

Properties

class Rectangle(object):def _ _init_ _(self, width, height):

self._ _width = widthself.height = height

def _area(self):return self._ _width * self.height # ‘self.’ is required!

area = property(fget=_area) # redefines field as method

def _width(self): return self._ _widthdef _setWidth(self, width): self._ _width = widthwidth = property(fget=_width, fset=_setWidth) # get & set

Special Methods

__init__ x=X()__call__ x()__eq__ x==y__ne__ x!=y <>__le__ x<=y__lt__ x<y__ge__ x>=y__gt__ x>yraise

NotImplementedErrordefault ops for x…y is

__cmp__ //2.x

__nonzero__ if x:

__repr__ y = eval(‘x’)

__str__ print x

__unicode__ print x

__getattr__ raise AttributeError

__getattribute__ x.i

__setattr__ x.i=1

More

__float__ float(x)__abs__ abs(x)__add__ x+y__iadd__ x+=y__radd__ y+x__mul__ x*y__imul__ x*=y__rmul__ y*x__floordiv__ x//y__ifloordiv____rfloordiv__

__int__ int(x)__neg__ -x__sub__ x-y__isub__ x-=y__rsub__ y-x__mod____imod____rmod____truediv__ x/y__itruediv____rtruediv__

repr

• repr returns the string of a constructor call to create the data: repr(x) (or `x` in v2.x)– the result should run if given as param to eval.– if no __str__, print x will use x.__repr__()

– “%r” in printf will automatically add quotes for strings, but not for numbers

Others

• There are also C-like bitshifting operators and octal, hexa conversion– <<,>>,&,|,^,~

• += add used if iadd (in-place add) not implemented• radd used if no available add for the left operand• __slots__ attribute of a class can be used to compactly

store more attributes (~5 times). Can contain __dict__ for dynamic new fields. Can be used only with fixed-size fields.__slots__=(‘a’,’b’)

Static Data & Methods

class Ballon(object):unique_colors = set() // static datadef __init__(self,color):

self.color = colorBalloon.unique_colors.add(color)

@staticmethod # decorator, one way of doingdef uniqueColorCount(): return len(Balloon.unique_colors)

def uniqueColors(): # the other wayreturn Balloon.unique_colors

uniquecolors = staticmethod(uniqueColors)

Decorators

• Can write own decorators (e.g. to log the method call, to update other values):– @logger– @recalculate

• ClassMethods are like static methods, but take as first parameter the class on which they are called: typically named “cls”– prefixed with decorator @classmethod

• Automatic elimination of tail recursion with @tailcall

Define logger exampledef trace( aFunc ): """Trace entry, exit and exceptions.""“ def loggedFunc( *args, **kw ):

print "enter", aFunc.__name__ try:

result= aFunc( *args, **kw ) except Exception, e:

print "exception", aFunc.__name__, e raise e

print "exit", aFunc.__name__ return result loggedFunc.__name__= aFunc.__name__ loggedFunc.__doc__= aFunc.__doc__ return loggedFunc

class MyClass( object ): @trace def __init__( self, someValue ): """Create a MyClass instance.""" self.value= someValue @trace def doSomething( self, anotherValue ): """Update a value.""“ self.value += anotherValue

>>> mc= MyClass( 23 ) enter __init__exit __init__

>>> mc.doSomething( 15 ) enter doSomething exit doSomething

>>> mc.value 38

Collection classes

• should implement corresponding methods• exceptions:

– mappings,sets: KeyError– sequences: IndexError

• Special Methods:__contains__ y in x__len__ len(x)__getitem__ c[k]__setitem__ x[k]=v__delitem__ del x[k]__iter__ for ... in x:

Inheritanceclass Painting(Item):

def __init__(self, artist, title, year=None):#super(Painting, self).__init__(artist, title,year) # previous

meth#Item.__init__(self,artist,title,year) # preferred for control

Two ways to call super __init__. Does not have to be the first call (unlike java). Does not have to be called if there is no parameter.

#Multiple inheritance: do it consistently, either use supper in all classes, or never.

Check if an object has method “title” with:

hasattr(item,”title”) and callable(item.title)isInstance(item, Item)

Abstract classes: all methods raise NotImplementedError

Modules

• A module can be a directory.– The directory should contain: __init__.py

• which could be empty

• shorten module names: – import mylib.length as length

Doctest

def add(x,y):“”” Adds two numbers. Doctest results for expected failures may be “Traceback (most recent call last):...IndexError: list”

>>> add(1,3)4“””return x+y

if __name__ == “__main__”:import doctestdoctest.testmod()

Packages

• There are many useful packages with extensions. E.g.:import bisect

bisect.insort_left(sorted_sequence,key) //inserts

bisect.bisect_left(sorted_sequence,key)//find

//index

Internationalization

• Qt provides QtLinguist (Chap 17)

• Have to provide strings with: QApplication.translate(“context”,”string”)

OS access

import osos.listdir(“/dir”) list of file names (bytes or strs,

function on what the parameter is)if parameter is str, files that are bytes are omitted

os.getcwdb() current working directory as bytesos.environ[‘HOME’] encoding defined by default

set with the LANG environment in UNIXos.path.dirname(__file__) path to local fileos.system(“echo \”Hello World!\””)