Basics

package/module/import

  • Python will search the imported module in directories defined in sys.path
  • packages(is also modules) are generally implemented as directories containing a special __init\_.py _file (executed when the package is imported)
  • __all__ = [] _in \_init\_.py _file controls what are imported when import * is used.

Styling

  • should maintain 2 empty lines between functions
  • Docstrings should be the first statement of a function or module. Docstrings provide help()
#!/usr/bin/env python3

"""Retrieve and print words from a URL

Usage:

"""

import sys
from urllib.request import urlopen

def fetch_words(url):
    """Fetch a list of words from a URL.

    Args:
        url: The URL of a UTF-8 text document.

    Returns:
        A list of strings containing the words from the document.
    """
    with urlopen(url) as story:
        story_words = []
        for line in story:
            line_words = line.decode('utf-8').split()
            for word in line_words:
                story_words.append(word)
    return story_words

Special Attributes

Special attributes in python are delimited by double underscores.

__name__ to determine how the module is being used.

if __name__ == 'words': # == name of the module, when imports, and it only execute once even import multiple times
    print(__name__)

if __name__ == '__main__': # when executing the .py script
    main(sys.argv[1])

'with' statement

class controlled_execution:
    def __enter__(self):
        set things up
        return thing
    def __exit__(self, type, value, traceback):
        tear things down

with controlled_execution() as thing:
     some code

when the “with” statement is executed, Python evaluates the expression, calls the __enter__ method on the resulting value (which is called a “context guard”), and assigns whatever __enter__ returns to the variable given by as. Python will then execute the code body, and no matter what happens in that code, call the guard object’s __exit__ method.

Context Manager

http://preshing.com/20110920/the-python-with-statement-by-example/

Default Parameter

Python’s default arguments are evaluated once when the function is defined, not each time the function is called (like it is in say, Ruby).

def append_to(element, to=[]):
    to.append(element)
    return to

What You Should Do Instead

Create a new object each time the function is called, by using a default arg to signal that no argument was provided (Noneis often a good choice).

def append_to(element, to=None):
    if to is None:
        to = []
    to.append(element)
    return to

Scope

LEGB rule: Local, Enclosing, Global, Built-in.

Below function will create a new local binding of "count".

Use global keyword to introduce names from global namespace into the local namespace. (reading the variable no need global keyword)

Use nonlocal keyword to introduce names from the enclosing namespace into the local namespace.

count = 0

def set_count(c):
    count = c

Numeric

shortest = float('inf')

Functions

def is executed in runtime -> functions are defined in runtime.

functions in python are first-class, treated like other objects.

#lambda function
lambda name: name.split()[-1]  #no need return keyword

#Unpacking Argument Lists
args = [3, 6]
range(*args)    # call with arguments unpacked from a list #[3, 4, 5]
#Similar fashion, dictionaries can deliver keyword arguments with the **-operator:
def parrot(voltage, state='a stiff', action='voom'):
     print "-- This parrot wouldn't", action,
     print "if you put", voltage, "volts through it.",
     print "E's", state, "!"
d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
parrot(**d)

#define functions accept arbitrary number of arguments. The arguments list should follow this order
def print_args(arg1, arg2, *args, kwarg1, kwarg2, **kwargs):

function factory: function that returns new, specialised functions

def raise_to(exp):
    def raise_to_exp(x):
        return pow(x, exp)
    return raise_to_exp

#python will create a closure to refer to the exp obj
square = raise_to(2)
square.__closure__

Generator

Python provides generator functions as a convenient shortcut to building iterators.

# a generator that yields items instead of returning a list
def firstn(n):
   num = 0
   while num < n:
      yield num
      num += 1

sum_of_first_n = sum(firstn(1000000))

Decorators

Modify or enhance functions without changing their definition.

@functools.wraps(f): properly update metadata on wrapped functions e.g. __name\_, \_doc\__

###################### function decorator ###################### 
def escape_unicode(f):
    @functools.wraps(f)
    def wrap(*args, **kwargs):
        x = f(*args, **kwargs)
        return ascii(x)
    return wrap

@escape_unicode
def northern_city(prefix):
    return prefix+'Troms@'

###################### class decorator ##########################
class CallCount:
    def __init__(self, f):
        self.f = f
        self.count = 0

    def __call__(self, *args, **kwargs):
        self.count += 1
        return self.f(*args, **kwargs)

@CallCount
def hello(name):
    print('Hello, {}'.format(name))

hello.count  #since the hello function is decorated as CallCount class instance. It has attribute count.

###################### instances as decorator #################### 
class Trace:
    def __init__(self):
        self.enabled = True

    def __call__(self, f):
        def wrap(*args, **kwargs):
            if self.enabled:
                print('Calling {}'.format(f))
            return f(*args, **kwargs)
        return wrap

tracer = Trace()

@tracer
def rotate_list(l):
    return l[1:] + [l[0]]

###################### multiple decorators ######################
@decorator1
@decorator2
@decorator3
def some_function():  #the decorators are evaluated at order of bottom to top

###################### Decorator can be applied to class methods ######################
class IslandMaker:
    def __init__(self, suffix):
        self.suffix = suffix

    @tracer
    def make_island(self, name):
        return name + self.suffix

###################### Decorator Factory ######################
def check_non_negative(index):
    def validator(f):
        def wrap(*args):
            if args[index] < 0:
                raise ValueError('Argument {} must be non-negative.'.format(index))
            return f(*args)
        return wrap
    return validator

@check_non_negative(1)  #this calls the check_non_negative function which returns the actual decorator
def create_list(value, size):
    return [value] * size

Exception Handling

try:
    return int(s)
except (TypeError, ValueError) as e:
    print("Conversion error: {}"\
            .format(str(e)),
            file=sys.stderr)
    raise
finally:

if x < 0:
    raise ValueError("Cannot compute square root of negative number {}".format(x))

Files and Resource Management

#write to file
try:
    f = open('wasteland.txt', mode='wt', encoding='utf-8')
    f.write('what are the roots that ...\n testing \n testing')
    f.writelines(sentences_list)
finally:
    f.close()   #need to close the file to flush the content

with open('wasteland.txt', mode='wt', encoding='utf-8') as f:
    f.write('what are the roots that ...\n testing \n testing')

#read from file
g = open('wasteland.txt', mode='rt', encoding='utf-8')
g.read(32) #read only 32 characters
g.read() #read all content, if we call it again, it will give '' as all content are read
g.seek(0) #reset to point to start of the file
g.readline() #will have \n at the end if it is not the last line
g.readlines()
g.close()

Language Specifics

  • Omitted return parameter (just return keyword) or implicit return at the end of function, returns None.
  • No variables concept, they are named references to objects.
  • Python is a dynamic type, but strong type system. (No implicit type conversion e.g. "answer is " + 3 will give type error. Except bool implicit conversion in if or condition statements.)
  • Everything in Python is object, including functions, modules, class .... dir() can be used to introspect an object and get its attributes. Metaclass e.g. type can be regarded as class of class object.

results matching ""

    No results matching ""