From 5d31cc05a622bbff24af6253cffbade1491c46ae Mon Sep 17 00:00:00 2001 From: Mark Pilgrim Date: Tue, 21 Apr 2009 00:03:51 -0400 Subject: [PATCH] stub for special-method-names chapter --- advanced-iterators.html | 1 + case-study-porting-chardet-to-python-3.html | 2 +- dip3.css | 4 +- examples/ordereddict.py | 83 +++++++ generators.html | 1 + iterators-and-generators.html | 65 ++++++ iterators.html | 8 +- native-datatypes.html | 1 + porting-code-to-python-3-with-2to3.html | 1 + refactoring.html | 1 + regular-expressions.html | 1 + special-method-names.html | 231 ++++++++++++++++++++ strings.html | 1 + unit-testing.html | 1 + your-first-python-program.html | 1 + 15 files changed, 397 insertions(+), 5 deletions(-) create mode 100644 examples/ordereddict.py create mode 100644 iterators-and-generators.html create mode 100644 special-method-names.html diff --git a/advanced-iterators.html b/advanced-iterators.html index dfc02c4..1e44b61 100644 --- a/advanced-iterators.html +++ b/advanced-iterators.html @@ -10,6 +10,7 @@ body{counter-reset:h1 7}
  

You are here: Home Dive Into Python 3 +

Difficulty level:

Advanced Iterators

Great fleas have little fleas upon their backs to bite ’em,
And little fleas have lesser fleas, and so ad infinitum.
— Augustus De Morgan diff --git a/case-study-porting-chardet-to-python-3.html b/case-study-porting-chardet-to-python-3.html index c6bb05e..09c6b42 100644 --- a/case-study-porting-chardet-to-python-3.html +++ b/case-study-porting-chardet-to-python-3.html @@ -14,6 +14,7 @@ del{background:#f87}

  

You are here: Home Dive Into Python 3 +

Difficulty level:

Case Study: Porting chardet to Python 3

Words, words. They’re all we have to go on.
Rosencrantz and Guildenstern are Dead @@ -1179,7 +1180,6 @@ tests\EUC-JP\arclamp.jp.xml EUC-JP with confide

© 2001–9 Mark Pilgrim diff --git a/dip3.css b/dip3.css index 1dba446..06f035e 100644 --- a/dip3.css +++ b/dip3.css @@ -69,7 +69,7 @@ p,ul,ol{margin:1.75em 0;font-size:medium} html{background:#fff;color:#222} body{margin:1.75em 28px} .c{clear:both;text-align:center;margin:2.154em 0} -form div{float:right} +form div,#level{float:right} .todo{color:#ddd} /* links */ @@ -117,4 +117,4 @@ aside{display:block;float:right;font-style:oblique;font-size:xx-large;width:25%; .nav a{text-decoration:none;border:0;display:block} .nav a:first-child{float:left} .nav a:last-child{float:right} -.nav span{font-size:1000%;line-height:1;margin:0} \ No newline at end of file +.nav span{font-size:1000%;line-height:1;margin:0} diff --git a/examples/ordereddict.py b/examples/ordereddict.py new file mode 100644 index 0000000..ccf39fc --- /dev/null +++ b/examples/ordereddict.py @@ -0,0 +1,83 @@ +# +# OrderedDict will be part of the collections module in Python 3.1. +# This is a standalone version for demonstration purposes only. +# If you're using Python 3.0, you should upgrade to Python 3.1, then +# >>> from collections import OrderedDict +# instead of using this version. +# +# Provenance: +# - PEP 372: OrderedDict http://www.python.org/dev/peps/pep-0372/ +# - Python bug 5397: implement PEP 372 http://bugs.python.org/issue5397 +# - Bug 5397 attachment: http://bugs.python.org/file13231/od7.diff +# + +from collections import MutableMapping +from itertools import zip_longest as _zip_longest + +class OrderedDict(dict, MutableMapping): + + def __init__(self, *args, **kwds): + if len(args) > 1: + raise TypeError('expected at most 1 arguments') + if not hasattr(self, '_keys'): + self._keys = [] + self.update(*args, **kwds) + + def clear(self): + del self._keys[:] + dict.clear(self) + + def __setitem__(self, key, value): + if key not in self: + self._keys.append(key) + dict.__setitem__(self, key, value) + + def __delitem__(self, key): + dict.__delitem__(self, key) + self._keys.remove(key) + + def __iter__(self): + return iter(self._keys) + + def __reversed__(self): + return reversed(self._keys) + + def popitem(self): + if not self: + raise KeyError('dictionary is empty') + key = self._keys.pop() + value = dict.pop(self, key) + return key, value + + def __reduce__(self): + items = [[k, self[k]] for k in self] + inst_dict = vars(self).copy() + inst_dict.pop('_keys', None) + return (self.__class__, (items,), inst_dict) + + setdefault = MutableMapping.setdefault + update = MutableMapping.update + pop = MutableMapping.pop + keys = MutableMapping.keys + values = MutableMapping.values + items = MutableMapping.items + + def __repr__(self): + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, list(self.items())) + + def copy(self): + return self.__class__(self) + + @classmethod + def fromkeys(cls, iterable, value=None): + d = cls() + for key in iterable: + d[key] = value + return d + + def __eq__(self, other): + if isinstance(other, OrderedDict): + return all(p==q for p, q in _zip_longest(self.items(), other.items())) + return dict.__eq__(self, other) diff --git a/generators.html b/generators.html index d6da5ea..8cc926b 100644 --- a/generators.html +++ b/generators.html @@ -10,6 +10,7 @@ body{counter-reset:h1 5}

  

You are here: Home Dive Into Python 3 +

Difficulty level:

Generators

My spelling is Wobbly. It's good spelling but it Wobbles, and the letters get in the wrong places.
— Winnie-the-Pooh diff --git a/iterators-and-generators.html b/iterators-and-generators.html new file mode 100644 index 0000000..a751fa2 --- /dev/null +++ b/iterators-and-generators.html @@ -0,0 +1,65 @@ + + + + +Secret Leftover Page - Dive into Python 3 + + + + +

  
+

You are here: Home Dive Into Python 3 +

Secret Leftover Page

+
+

You step in the stream / but the water has moved on. / This page is not here.
— 404 Not Found haiku +

+

  +

Huh?

+

This book used to have a chapter called “Iterators & Generators,” but I split the chapter in half so I could introduce Python classes before talking about iterators. The content that used to be at this address is now in one of those two chapters: + +

+ + + +

© 2001–9 Mark Pilgrim + + diff --git a/iterators.html b/iterators.html index c8163b6..9cfb338 100644 --- a/iterators.html +++ b/iterators.html @@ -10,13 +10,16 @@ body{counter-reset:h1 6}

  

You are here: Home Dive Into Python 3 +

Difficulty level:

Iterators

East is East, and West is West, and never the twain shall meet.
Rudyard Kipling

 

Diving In

-

Generators are really just a special case of iterators. A function that yields values is a nice, compact way of building an iterator without building an iterator. Remember the Fibonacci generator? Here it is as a built-from-scratch iterator: +

Generators are really just a special case of iterators. A function that yields values is a nice, compact way of building an iterator without building an iterator. Let me show you what I mean by that. + +

Remember the Fibonacci generator? Here it is as a built-from-scratch iterator:

[download fibonacci2.py]

class Fib:
@@ -48,10 +51,11 @@ body{counter-reset:h1 6}
 
 

 class PapayaWhip:  
-    pass           
+ pass
  1. The name of this class is PapayaWhip, and it doesn't inherit from any other class. Class names are usually capitalized, EachWordLikeThis, but this is only a convention, not a requirement.
  2. You probably guessed this, but everything in a class is indented, just like the code within a function, if statement, for loop, or any other block of code. The first line not indented is outside the class. +

This PapayaWhip class doesn't define any methods or attributes, but syntactically, there needs to be something in the definition, thus the pass statement. This is a Python reserved word that just means “move along, nothing to see here”. It's a statement that does nothing, and it's a good placeholder when you're stubbing out functions or classes. diff --git a/native-datatypes.html b/native-datatypes.html index b373e9d..9f1df47 100644 --- a/native-datatypes.html +++ b/native-datatypes.html @@ -10,6 +10,7 @@ body{counter-reset:h1 2}

  

You are here: Home Dive Into Python 3 +

Difficulty level:

Native Datatypes

Wonder is the foundation of all philosophy, inquiry its progress, ignorance its end.
— Michel de Montaigne diff --git a/porting-code-to-python-3-with-2to3.html b/porting-code-to-python-3-with-2to3.html index cf75c36..2c0069e 100644 --- a/porting-code-to-python-3-with-2to3.html +++ b/porting-code-to-python-3-with-2to3.html @@ -20,6 +20,7 @@ td pre{padding:0;border:0}

  

You are here: Home Dive Into Python 3 +

Difficulty level:

Porting Code to Python 3 with 2to3

Life is pleasant. Death is peaceful. It’s the transition that’s troublesome.
— Isaac Asimov (attributed) diff --git a/refactoring.html b/refactoring.html index 97e6ddf..1087857 100644 --- a/refactoring.html +++ b/refactoring.html @@ -10,6 +10,7 @@ body{counter-reset:h1 10}

  

You are here: Home Dive Into Python 3 +

Difficulty level:

Refactoring

After one has played a vast quantity of notes and more notes, it is simplicity that emerges as the crowning reward of art.
Frédéric Chopin diff --git a/regular-expressions.html b/regular-expressions.html index ad041dc..6c987fb 100644 --- a/regular-expressions.html +++ b/regular-expressions.html @@ -10,6 +10,7 @@ body{counter-reset:h1 4}

  

You are here: Home Dive Into Python 3 +

Difficulty level:

Regular Expressions

Some people, when confronted with a problem, think “I know, I’ll use regular expressions.” Now they have two problems.
Jamie Zawinski diff --git a/special-method-names.html b/special-method-names.html new file mode 100644 index 0000000..643609e --- /dev/null +++ b/special-method-names.html @@ -0,0 +1,231 @@ + + + +Special Method Names - Dive into Python 3 + + + + + +

  
+

You are here: Home Dive Into Python 3 +

Difficulty level: +

Special Method Names

+
+

FIXME
— FIXME +

+

  +

Diving In

+

FIXME + +

[download ordereddict.py] +

import collections
+import itertools
+ 
+class OrderedDict(dict, collections.MutableMapping):
+
+    def __init__(self, *args, **kwds):
+        if len(args) > 1:
+            raise TypeError('expected at most 1 arguments')
+        if not hasattr(self, '_keys'):
+            self._keys = []
+        self.update(*args, **kwds)
+
+    def clear(self):
+        del self._keys[:]
+        dict.clear(self)
+
+    def __setitem__(self, key, value):
+        if key not in self:
+            self._keys.append(key)
+        dict.__setitem__(self, key, value)
+
+    def __delitem__(self, key):
+        dict.__delitem__(self, key)
+        self._keys.remove(key)
+
+    def __iter__(self):
+        return iter(self._keys)
+
+    def __reversed__(self):
+        return reversed(self._keys)
+
+    def popitem(self):
+        if not self:
+            raise KeyError('dictionary is empty')
+        key = self._keys.pop()
+        value = dict.pop(self, key)
+        return key, value
+
+    def __reduce__(self):
+        items = [[k, self[k]] for k in self]
+        inst_dict = vars(self).copy()
+        inst_dict.pop('_keys', None)
+        return (self.__class__, (items,), inst_dict)
+
+    setdefault = MutableMapping.setdefault
+    update = MutableMapping.update
+    pop = MutableMapping.pop
+    keys = MutableMapping.keys
+    values = MutableMapping.values
+    items = MutableMapping.items
+
+    def __repr__(self):
+        if not self:
+            return '%s()' % (self.__class__.__name__,)
+        return '%s(%r)' % (self.__class__.__name__, list(self.items()))
+
+    def copy(self):
+        return self.__class__(self)
+
+    @classmethod
+    def fromkeys(cls, iterable, value=None):
+        d = cls()
+        for key in iterable:
+            d[key] = value
+        return d
+
+    def __eq__(self, other):
+        if isinstance(other, OrderedDict):
+            return all(p==q for p, q in itertools.zip_longest(self.items(), other.items()))
+        return dict.__eq__(self, other)
+ + + +

© 2001–9 Mark Pilgrim + + diff --git a/strings.html b/strings.html index bab41e6..6c158da 100644 --- a/strings.html +++ b/strings.html @@ -11,6 +11,7 @@ body{counter-reset:h1 3}

  

You are here: Home Dive Into Python 3 +

Difficulty level:

Strings

I’m telling you this ’cause you’re one of my friends.
diff --git a/unit-testing.html b/unit-testing.html index 4bdad52..3c5ea35 100644 --- a/unit-testing.html +++ b/unit-testing.html @@ -10,6 +10,7 @@ body{counter-reset:h1 8}

  

You are here: Home Dive Into Python 3 +

Difficulty level:

Unit Testing

Certitude is not the test of certainty. We have been cocksure of many things that were not so.
Oliver Wendell Holmes, Jr. diff --git a/your-first-python-program.html b/your-first-python-program.html index e85d831..eaf7dba 100644 --- a/your-first-python-program.html +++ b/your-first-python-program.html @@ -13,6 +13,7 @@ th{text-align:left}

  

You are here: Home Dive Into Python 3 +

Difficulty level:

Your First Python Program

Don’t bury your burden in saintly silence. You have a problem? Great. Rejoice, dive in, and investigate.
Ven. Henepola Gunaratana