1 / 44

Advanced Python I

Advanced Python I. by Raymond Hettinger @ raymondh. Files used in this tutorial. http:// dl.dropbox.com /u/3967849/ advpython.zip Or in shortened form: http :// bit.ly / fboKwT. w hoami id -un. PSF board member Python core developer since 2001

desma
Télécharger la présentation

Advanced Python I

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Advanced Python I by Raymond Hettinger @raymondh

  2. Files used in this tutorial http://dl.dropbox.com/u/3967849/advpython.zip Or in shortened form: http://bit.ly/fboKwT

  3. whoami id -un PSF board member Python core developer since 2001 Author of the itertools module, set objects, sorting key functions, and many tools that you use every day Consultant for training, code review, design and optimization Background in data visualization and high-frequency trading Person who is very interested in your success with Python @raymondh on twitter

  4. Background and Expectations What is the background of the participants? Who is beginner/intermediate moving to next level? Who is already somewhat advanced? What do you want to be able to do after the tutorial?

  5. What does in mean to be Advanced? Know all of the basic language constructs and how they are used Understand the performance implications of various coding methods Understand how Python works Have seen various expert coding styles Actively use the docs as you code Know how to find and read source code Take advantage of programming in a dynamic language Become part of the Python community In short, an advanced Python programmer becomes well-equipped to solve a variety of problems by fully exploiting the language and its many resources.

  6. Foundation Skills for the Tutorial • Accessing the documentation: • F1 on IDLE • Applications Directory or Window’s Start Menu • Doc/index.html on the class resource disk • The interactive prompt: • IDLE, iPython, PyCharm, Wing-IDE, etc • command-line prompt with readline • PYTHONSTARTUP=~/pystartup.py # tab-completion • Command line tools: python –m test.pystone python –m pdb python –m test.regrtest

  7. Two Part Tutorial • The morning will be full of techniques and examples designed to open your mind about Python’s capabilities. • There will be periodic hands-on exercises • The afternoon will have three parts: • All about Unicode • A sit back and relax presentation about descriptors • Guided exercises and problem sets

  8. Foundation Skills for the Tutorial • IDLE’s module loader • performs the same search as “import m” • fastest way to find relevant source no matter where it is • Mac users should map “Control Key M” to “open-module” • IDLE’s class browser • hidden gem • fastest way to navigate unfamiliar source code • Control or Apple B • Try it with the decimal module

  9. Handy techniques for next section • Bound methods are just like other callables: >>> s= [] >>> s_append = s.append >>> s_append(3) >>> s_append(5) >>> s_append(7) >>> s [3, 5, 7] • Accessing function names: >>> deffizzle(a, b, c): … >>> fizzle.__name__ 'fizzle’

  10. Optimizations • Replace global lookups with local lookups • Builtin names: list, int, string, ValueError • Module names: collections, copy, urllib • Global variables: even one that look like constants • Use bound methods • bm = g.foo • bm(x) # same as g.foo(x) • Minimize pure-python function calls inside a loop • A new stack frame is created on *every* call • Recursion is expensive in Python

  11. Unoptimized Example defone_third(x): return x / 3.0 defmake_table(pairs): result = [] for value in pairs: x = one_third(value) result.append(format(value, '9.5f’)) return '\n'.join(result)

  12. Optimized version defmake_table(pairs): result = [] result_append = result.append# bound method _format = format # localized for value in pairs: x = value / 3.0 # in-lined result_append(_format(value, '9.5f')) return '\n'.join(result)

  13. Loop Invariant Code Motion def dispatch(self, commands): for cmd in commands: cmd = {'duck': 'hide', 'shoot': 'fire'}.get(cmd, cmd) log(cmd) do(cmd) def dispatch(self, commands): translate = {'duck': 'hide', 'shoot': 'fire'} for cmd in commands: cmd = translate.get(cmd, cmd) log(cmd) do(cmd)

  14. Vectorization Replace CPython’seval-loop with a C function that does all the work: [ord(c) for c in long_string]  list(map(ord, long_string)) [i**2 for i in range(100)]  list(map(pow, count(0), repeat(2, 100)))

  15. Timing Technique if __name__=='__main__': from timeit import Timer from random import random n = 10000 pairs = [random() for i in range(n)] setup = "from __main__ import make_table, make_table2, pairs" for func in make_table, make_table2: stmt = '{0.__name__}(pairs)'.format(func) print(func.__name__, min(Timer(stmt, setup).repeat(7, 20)))

  16. Class Exercise File: optimization.py

  17. Goal Check • Learn 5 techniques for optimization: • Vectorization • Localization • Bound Methods • Loop Invariant Code Motion • Reduce Function Calls • Learn to measure performance with timeit.Timer() • See how the “import __main__” technique beats using strings • Use func.__name__ in a loop • Practice using itertools

  18. Handy techniques for next section • pprint.pprint(nested_data_structure) • help(pow) • functools.partial() >>> two_to = partial(pow, 2) >>> two_to(5) 32

  19. Think in terms of dictionaries • Files: thinkdict/regular.py and thinkdict/dict_version.py • Experiments: import collections vars(collections) dir(collections.OrderedDict) type(collections) dir(collections.Counter(‘abracadabra’)) globals() help(instance) • Goal is to see dicts where other see modules, classes, instances, and other Python lifeforms

  20. Add a little polish • Keyword arguments • Docstrings • Doctests doctest.testmod() • Named tuples print(doctest.testmod())

  21. ChainMap • Common Pattern (but slow): defgetvar(name, cmd_line_args, environ_vars, default_values): d = default_values.copy() d.update(environ) d.update(cmd_line_args) return d[name] • Instead, link several dictionaries (or other mappings together for a quick single lookup): defgetvar(name, cmd_line_args, environ_vars, default_values): d = ChainMap(cmd_line_args, environ_vars, default_values) return d[name]

  22. Examples in Real Code Lib/string.py # search for Template http://hg.python.org/cpython/file/default/Lib/configparser.py http://hg.python.org/cpython/file/default/Lib/collections.py

  23. Goal Check Learn to see dictionaries where others see native python objects, classes, modules, etc. Develop an understanding of attribute and method lookup logic See how ChainMap() is used in real code

  24. Who owns the dot? • Take charge of the dot with __getattribute__ • Class demo: own_the_dot/custom_getattribute • Basic Idea: Every time there is an attribute lookup Check the object found to see if it is an object of interest If so, invoke a method on that object

  25. Class Exercise Make a class with a custom __getattribute__ that behaves normally, but logs each calls to stderr.

  26. Goal Check Learn the underpinning of how descriptors are implemented Gain the ability to intercept attribute lookup and control the behavior of the dot. Deepen you understanding of attribute and method lookup logic

  27. Exploiting Polymorphism • Symbolic Expansion: x + y where x and y are strings • Example Files: • tracers/symbol_expansion.py • tracers/approximate.py • Alternative to logging calls

  28. Generating code • Create code dynamically • Used when code can be parameterized or described succinctly • Two ways to load • exec() • import • Examples: • collections.namedtuple() • codegen.py • Ply introspects docstrings

  29. Dynamic method discovery • Framework technique that lets subclasses define new methods • Dispatch to a given name is simple: func = getattr(self, 'do_' + cmd) return func(arg) • Given cmd==‘move’, this code makes a call to do_move(arg) • See Lib/cmd.py at line 211 • See an example of a turtle shell in the cmd docs

  30. Goal Check Learn how to evaluate functions symbolically Be able to generate code on the fly and load it with either exec() or an import. Know that docstrings can be used to guide code generation. Works well with a pattern->action style of coding. Be able to implement dynamic method discovery in a framework like cmd.py

  31. Loops with Else-Clauses

  32. Slicing

  33. Negative Slicing

  34. Sorting skills • See the sorting HowTo guide for details • Key functions: • key = str.upper # bound method • key = lambda s: s.upper() # lambda • key = itemgetter(2, 4) # third field and fifth field • key = attrgetter(‘lastname’, ‘firstname’) • key = locale.strxfrm() • SQL style with primary and secondary keys

  35. Sorting skills • Schwartzian transform: decorated = [(func(record), record) for record in records] decorated.sort() result = [record for key, record in records] • Sort stability and multiple passes: s.sort(key=attrgetter(‘lastname)) # Secondary key s.sort(key=attrgetter(‘age’), reverse=True) # Primary key

  36. Goal Check Review Python basics with an eye towards mastery Loops with else-clauses Slicing invariants Handling of negative indicies Sorting skills

  37. Collections • Deque – Fast O(1) appends and pop from both ends d.append(10) # add to right side d.popleft() # fetch from left side • Named Tuples – Like regular tuples, but also allows access using named attributes Point = namedtuple(‘Point’, ‘x y’) p = Point(10, 20) print p.x • Defaultdict – Like a regular dictionary but supplies a factory function to fill-in missing values d = defaultdict(list) d[k].append(v) # new keys create new lists • Counter – A dictionary that knows how to count c = Counter() c[k] += 2 # zero value assumed for new key • OrderedDict – A dictionary that remembers insertion order

  38. LRU Cache • Simple unbounded cache: def f(*args, cache={}) if args in cache: return cache[args] result = big_computation(*args) cache[args] = result return result • But, that would grow without bound • To limit its size, we need to throw-away least recently used entries • Provided in the standard library as a decorator: @functools.lru_cache(maxsize=100) defbig_computation(*args): ...

  39. Dynamic Programming with a Cache @lru_cache() deffibonacci(n): if n <= 1: return n return fibonacci(n-1) + fibonacci(n-2) print(fibonacci(100))

  40. Running trace from the command line • python3.2 -m trace --count fibonacci.py • Contents of fibonacci.cover: 1: from functools import lru_cache 1: @lru_cache() deffibonacci(n): 101: if n <= 1: 2: return n 99: return fibonacci(n-1) + fibonacci(n-2) 1: print(fibonacci(100))

  41. OrderedDict used to implement the LRU Cache def f(*args, cache=OrderedDict()) if args in cache: result = cache[args] del cache[args] cache[args] = result return result result = big_computation(*args) cache[args] = result if len(cache) > maxsize: cache.pop(0) return result

  42. Implicit Exception Chaining try: 1 / 0 except ZeroDivisionError: raise ValueError Traceback (most recent call last): 1 / 0 ZeroDivisionError: division by zero During handling of the above exception, another exception occurred: Traceback (most recent call last): raise ValueError ValueError

  43. Explicit Exception Chaining try: 1 / 0 except ZeroDivisionError as e: raise ValueError from e Traceback (most recent call last): 1 / 0 ZeroDivisionError: division by zero During handling of the above exception, another exception occurred: Traceback (most recent call last): raise ValueError ValueError

  44. Hierarchy issues with Exceptions Sometimes it is inconvenient that exceptions are arranged in a hierarchy We would sometimes likes to be able to raise multiple kinds of exceptions all at once. The decimal module faces this challenge class DivisionByZero(DecimalException, ZeroDivisionError): class DivisionUndefined(InvalidOperation, ZeroDivisionError): class Inexact(DecimalException): class InvalidContext(InvalidOperation): class Rounded(DecimalException): class Subnormal(DecimalException): class Overflow(Inexact, Rounded): class Underflow(Inexact, Rounded, Subnormal):

More Related