These files are a subset of the python-2.7.2.tgz distribution from python.org. Changed files from PyMod-2.7.2 have been copied into the corresponding directories of this tree, replacing the original files in the distribution. Signed-off-by: daryl.mcdaniel@intel.com git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13197 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			498 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			498 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # This contains most of the executable examples from Guido's descr
 | |
| # tutorial, once at
 | |
| #
 | |
| #     http://www.python.org/2.2/descrintro.html
 | |
| #
 | |
| # A few examples left implicit in the writeup were fleshed out, a few were
 | |
| # skipped due to lack of interest (e.g., faking super() by hand isn't
 | |
| # of much interest anymore), and a few were fiddled to make the output
 | |
| # deterministic.
 | |
| 
 | |
| from test.test_support import sortdict
 | |
| import pprint
 | |
| 
 | |
| class defaultdict(dict):
 | |
|     def __init__(self, default=None):
 | |
|         dict.__init__(self)
 | |
|         self.default = default
 | |
| 
 | |
|     def __getitem__(self, key):
 | |
|         try:
 | |
|             return dict.__getitem__(self, key)
 | |
|         except KeyError:
 | |
|             return self.default
 | |
| 
 | |
|     def get(self, key, *args):
 | |
|         if not args:
 | |
|             args = (self.default,)
 | |
|         return dict.get(self, key, *args)
 | |
| 
 | |
|     def merge(self, other):
 | |
|         for key in other:
 | |
|             if key not in self:
 | |
|                 self[key] = other[key]
 | |
| 
 | |
| test_1 = """
 | |
| 
 | |
| Here's the new type at work:
 | |
| 
 | |
|     >>> print defaultdict               # show our type
 | |
|     <class 'test.test_descrtut.defaultdict'>
 | |
|     >>> print type(defaultdict)         # its metatype
 | |
|     <type 'type'>
 | |
|     >>> a = defaultdict(default=0.0)    # create an instance
 | |
|     >>> print a                         # show the instance
 | |
|     {}
 | |
|     >>> print type(a)                   # show its type
 | |
|     <class 'test.test_descrtut.defaultdict'>
 | |
|     >>> print a.__class__               # show its class
 | |
|     <class 'test.test_descrtut.defaultdict'>
 | |
|     >>> print type(a) is a.__class__    # its type is its class
 | |
|     True
 | |
|     >>> a[1] = 3.25                     # modify the instance
 | |
|     >>> print a                         # show the new value
 | |
|     {1: 3.25}
 | |
|     >>> print a[1]                      # show the new item
 | |
|     3.25
 | |
|     >>> print a[0]                      # a non-existent item
 | |
|     0.0
 | |
|     >>> a.merge({1:100, 2:200})         # use a dict method
 | |
|     >>> print sortdict(a)               # show the result
 | |
|     {1: 3.25, 2: 200}
 | |
|     >>>
 | |
| 
 | |
| We can also use the new type in contexts where classic only allows "real"
 | |
| dictionaries, such as the locals/globals dictionaries for the exec
 | |
| statement or the built-in function eval():
 | |
| 
 | |
|     >>> def sorted(seq):
 | |
|     ...     seq.sort(key=str)
 | |
|     ...     return seq
 | |
|     >>> print sorted(a.keys())
 | |
|     [1, 2]
 | |
|     >>> exec "x = 3; print x" in a
 | |
|     3
 | |
|     >>> print sorted(a.keys())
 | |
|     [1, 2, '__builtins__', 'x']
 | |
|     >>> print a['x']
 | |
|     3
 | |
|     >>>
 | |
| 
 | |
| Now I'll show that defaultdict instances have dynamic instance variables,
 | |
| just like classic classes:
 | |
| 
 | |
|     >>> a.default = -1
 | |
|     >>> print a["noway"]
 | |
|     -1
 | |
|     >>> a.default = -1000
 | |
|     >>> print a["noway"]
 | |
|     -1000
 | |
|     >>> 'default' in dir(a)
 | |
|     True
 | |
|     >>> a.x1 = 100
 | |
|     >>> a.x2 = 200
 | |
|     >>> print a.x1
 | |
|     100
 | |
|     >>> d = dir(a)
 | |
|     >>> 'default' in d and 'x1' in d and 'x2' in d
 | |
|     True
 | |
|     >>> print sortdict(a.__dict__)
 | |
|     {'default': -1000, 'x1': 100, 'x2': 200}
 | |
|     >>>
 | |
| """
 | |
| 
 | |
| class defaultdict2(dict):
 | |
|     __slots__ = ['default']
 | |
| 
 | |
|     def __init__(self, default=None):
 | |
|         dict.__init__(self)
 | |
|         self.default = default
 | |
| 
 | |
|     def __getitem__(self, key):
 | |
|         try:
 | |
|             return dict.__getitem__(self, key)
 | |
|         except KeyError:
 | |
|             return self.default
 | |
| 
 | |
|     def get(self, key, *args):
 | |
|         if not args:
 | |
|             args = (self.default,)
 | |
|         return dict.get(self, key, *args)
 | |
| 
 | |
|     def merge(self, other):
 | |
|         for key in other:
 | |
|             if key not in self:
 | |
|                 self[key] = other[key]
 | |
| 
 | |
| test_2 = """
 | |
| 
 | |
| The __slots__ declaration takes a list of instance variables, and reserves
 | |
| space for exactly these in the instance. When __slots__ is used, other
 | |
| instance variables cannot be assigned to:
 | |
| 
 | |
|     >>> a = defaultdict2(default=0.0)
 | |
|     >>> a[1]
 | |
|     0.0
 | |
|     >>> a.default = -1
 | |
|     >>> a[1]
 | |
|     -1
 | |
|     >>> a.x1 = 1
 | |
|     Traceback (most recent call last):
 | |
|       File "<stdin>", line 1, in ?
 | |
|     AttributeError: 'defaultdict2' object has no attribute 'x1'
 | |
|     >>>
 | |
| 
 | |
| """
 | |
| 
 | |
| test_3 = """
 | |
| 
 | |
| Introspecting instances of built-in types
 | |
| 
 | |
| For instance of built-in types, x.__class__ is now the same as type(x):
 | |
| 
 | |
|     >>> type([])
 | |
|     <type 'list'>
 | |
|     >>> [].__class__
 | |
|     <type 'list'>
 | |
|     >>> list
 | |
|     <type 'list'>
 | |
|     >>> isinstance([], list)
 | |
|     True
 | |
|     >>> isinstance([], dict)
 | |
|     False
 | |
|     >>> isinstance([], object)
 | |
|     True
 | |
|     >>>
 | |
| 
 | |
| Under the new proposal, the __methods__ attribute no longer exists:
 | |
| 
 | |
|     >>> [].__methods__
 | |
|     Traceback (most recent call last):
 | |
|       File "<stdin>", line 1, in ?
 | |
|     AttributeError: 'list' object has no attribute '__methods__'
 | |
|     >>>
 | |
| 
 | |
| Instead, you can get the same information from the list type:
 | |
| 
 | |
|     >>> pprint.pprint(dir(list))    # like list.__dict__.keys(), but sorted
 | |
|     ['__add__',
 | |
|      '__class__',
 | |
|      '__contains__',
 | |
|      '__delattr__',
 | |
|      '__delitem__',
 | |
|      '__delslice__',
 | |
|      '__doc__',
 | |
|      '__eq__',
 | |
|      '__format__',
 | |
|      '__ge__',
 | |
|      '__getattribute__',
 | |
|      '__getitem__',
 | |
|      '__getslice__',
 | |
|      '__gt__',
 | |
|      '__hash__',
 | |
|      '__iadd__',
 | |
|      '__imul__',
 | |
|      '__init__',
 | |
|      '__iter__',
 | |
|      '__le__',
 | |
|      '__len__',
 | |
|      '__lt__',
 | |
|      '__mul__',
 | |
|      '__ne__',
 | |
|      '__new__',
 | |
|      '__reduce__',
 | |
|      '__reduce_ex__',
 | |
|      '__repr__',
 | |
|      '__reversed__',
 | |
|      '__rmul__',
 | |
|      '__setattr__',
 | |
|      '__setitem__',
 | |
|      '__setslice__',
 | |
|      '__sizeof__',
 | |
|      '__str__',
 | |
|      '__subclasshook__',
 | |
|      'append',
 | |
|      'count',
 | |
|      'extend',
 | |
|      'index',
 | |
|      'insert',
 | |
|      'pop',
 | |
|      'remove',
 | |
|      'reverse',
 | |
|      'sort']
 | |
| 
 | |
| The new introspection API gives more information than the old one:  in
 | |
| addition to the regular methods, it also shows the methods that are
 | |
| normally invoked through special notations, e.g. __iadd__ (+=), __len__
 | |
| (len), __ne__ (!=). You can invoke any method from this list directly:
 | |
| 
 | |
|     >>> a = ['tic', 'tac']
 | |
|     >>> list.__len__(a)          # same as len(a)
 | |
|     2
 | |
|     >>> a.__len__()              # ditto
 | |
|     2
 | |
|     >>> list.append(a, 'toe')    # same as a.append('toe')
 | |
|     >>> a
 | |
|     ['tic', 'tac', 'toe']
 | |
|     >>>
 | |
| 
 | |
| This is just like it is for user-defined classes.
 | |
| """
 | |
| 
 | |
| test_4 = """
 | |
| 
 | |
| Static methods and class methods
 | |
| 
 | |
| The new introspection API makes it possible to add static methods and class
 | |
| methods. Static methods are easy to describe: they behave pretty much like
 | |
| static methods in C++ or Java. Here's an example:
 | |
| 
 | |
|     >>> class C:
 | |
|     ...
 | |
|     ...     @staticmethod
 | |
|     ...     def foo(x, y):
 | |
|     ...         print "staticmethod", x, y
 | |
| 
 | |
|     >>> C.foo(1, 2)
 | |
|     staticmethod 1 2
 | |
|     >>> c = C()
 | |
|     >>> c.foo(1, 2)
 | |
|     staticmethod 1 2
 | |
| 
 | |
| Class methods use a similar pattern to declare methods that receive an
 | |
| implicit first argument that is the *class* for which they are invoked.
 | |
| 
 | |
|     >>> class C:
 | |
|     ...     @classmethod
 | |
|     ...     def foo(cls, y):
 | |
|     ...         print "classmethod", cls, y
 | |
| 
 | |
|     >>> C.foo(1)
 | |
|     classmethod test.test_descrtut.C 1
 | |
|     >>> c = C()
 | |
|     >>> c.foo(1)
 | |
|     classmethod test.test_descrtut.C 1
 | |
| 
 | |
|     >>> class D(C):
 | |
|     ...     pass
 | |
| 
 | |
|     >>> D.foo(1)
 | |
|     classmethod test.test_descrtut.D 1
 | |
|     >>> d = D()
 | |
|     >>> d.foo(1)
 | |
|     classmethod test.test_descrtut.D 1
 | |
| 
 | |
| This prints "classmethod __main__.D 1" both times; in other words, the
 | |
| class passed as the first argument of foo() is the class involved in the
 | |
| call, not the class involved in the definition of foo().
 | |
| 
 | |
| But notice this:
 | |
| 
 | |
|     >>> class E(C):
 | |
|     ...     @classmethod
 | |
|     ...     def foo(cls, y): # override C.foo
 | |
|     ...         print "E.foo() called"
 | |
|     ...         C.foo(y)
 | |
| 
 | |
|     >>> E.foo(1)
 | |
|     E.foo() called
 | |
|     classmethod test.test_descrtut.C 1
 | |
|     >>> e = E()
 | |
|     >>> e.foo(1)
 | |
|     E.foo() called
 | |
|     classmethod test.test_descrtut.C 1
 | |
| 
 | |
| In this example, the call to C.foo() from E.foo() will see class C as its
 | |
| first argument, not class E. This is to be expected, since the call
 | |
| specifies the class C. But it stresses the difference between these class
 | |
| methods and methods defined in metaclasses (where an upcall to a metamethod
 | |
| would pass the target class as an explicit first argument).
 | |
| """
 | |
| 
 | |
| test_5 = """
 | |
| 
 | |
| Attributes defined by get/set methods
 | |
| 
 | |
| 
 | |
|     >>> class property(object):
 | |
|     ...
 | |
|     ...     def __init__(self, get, set=None):
 | |
|     ...         self.__get = get
 | |
|     ...         self.__set = set
 | |
|     ...
 | |
|     ...     def __get__(self, inst, type=None):
 | |
|     ...         return self.__get(inst)
 | |
|     ...
 | |
|     ...     def __set__(self, inst, value):
 | |
|     ...         if self.__set is None:
 | |
|     ...             raise AttributeError, "this attribute is read-only"
 | |
|     ...         return self.__set(inst, value)
 | |
| 
 | |
| Now let's define a class with an attribute x defined by a pair of methods,
 | |
| getx() and and setx():
 | |
| 
 | |
|     >>> class C(object):
 | |
|     ...
 | |
|     ...     def __init__(self):
 | |
|     ...         self.__x = 0
 | |
|     ...
 | |
|     ...     def getx(self):
 | |
|     ...         return self.__x
 | |
|     ...
 | |
|     ...     def setx(self, x):
 | |
|     ...         if x < 0: x = 0
 | |
|     ...         self.__x = x
 | |
|     ...
 | |
|     ...     x = property(getx, setx)
 | |
| 
 | |
| Here's a small demonstration:
 | |
| 
 | |
|     >>> a = C()
 | |
|     >>> a.x = 10
 | |
|     >>> print a.x
 | |
|     10
 | |
|     >>> a.x = -10
 | |
|     >>> print a.x
 | |
|     0
 | |
|     >>>
 | |
| 
 | |
| Hmm -- property is builtin now, so let's try it that way too.
 | |
| 
 | |
|     >>> del property  # unmask the builtin
 | |
|     >>> property
 | |
|     <type 'property'>
 | |
| 
 | |
|     >>> class C(object):
 | |
|     ...     def __init__(self):
 | |
|     ...         self.__x = 0
 | |
|     ...     def getx(self):
 | |
|     ...         return self.__x
 | |
|     ...     def setx(self, x):
 | |
|     ...         if x < 0: x = 0
 | |
|     ...         self.__x = x
 | |
|     ...     x = property(getx, setx)
 | |
| 
 | |
| 
 | |
|     >>> a = C()
 | |
|     >>> a.x = 10
 | |
|     >>> print a.x
 | |
|     10
 | |
|     >>> a.x = -10
 | |
|     >>> print a.x
 | |
|     0
 | |
|     >>>
 | |
| """
 | |
| 
 | |
| test_6 = """
 | |
| 
 | |
| Method resolution order
 | |
| 
 | |
| This example is implicit in the writeup.
 | |
| 
 | |
| >>> class A:    # classic class
 | |
| ...     def save(self):
 | |
| ...         print "called A.save()"
 | |
| >>> class B(A):
 | |
| ...     pass
 | |
| >>> class C(A):
 | |
| ...     def save(self):
 | |
| ...         print "called C.save()"
 | |
| >>> class D(B, C):
 | |
| ...     pass
 | |
| 
 | |
| >>> D().save()
 | |
| called A.save()
 | |
| 
 | |
| >>> class A(object):  # new class
 | |
| ...     def save(self):
 | |
| ...         print "called A.save()"
 | |
| >>> class B(A):
 | |
| ...     pass
 | |
| >>> class C(A):
 | |
| ...     def save(self):
 | |
| ...         print "called C.save()"
 | |
| >>> class D(B, C):
 | |
| ...     pass
 | |
| 
 | |
| >>> D().save()
 | |
| called C.save()
 | |
| """
 | |
| 
 | |
| class A(object):
 | |
|     def m(self):
 | |
|         return "A"
 | |
| 
 | |
| class B(A):
 | |
|     def m(self):
 | |
|         return "B" + super(B, self).m()
 | |
| 
 | |
| class C(A):
 | |
|     def m(self):
 | |
|         return "C" + super(C, self).m()
 | |
| 
 | |
| class D(C, B):
 | |
|     def m(self):
 | |
|         return "D" + super(D, self).m()
 | |
| 
 | |
| 
 | |
| test_7 = """
 | |
| 
 | |
| Cooperative methods and "super"
 | |
| 
 | |
| >>> print D().m() # "DCBA"
 | |
| DCBA
 | |
| """
 | |
| 
 | |
| test_8 = """
 | |
| 
 | |
| Backwards incompatibilities
 | |
| 
 | |
| >>> class A:
 | |
| ...     def foo(self):
 | |
| ...         print "called A.foo()"
 | |
| 
 | |
| >>> class B(A):
 | |
| ...     pass
 | |
| 
 | |
| >>> class C(A):
 | |
| ...     def foo(self):
 | |
| ...         B.foo(self)
 | |
| 
 | |
| >>> C().foo()
 | |
| Traceback (most recent call last):
 | |
|  ...
 | |
| TypeError: unbound method foo() must be called with B instance as first argument (got C instance instead)
 | |
| 
 | |
| >>> class C(A):
 | |
| ...     def foo(self):
 | |
| ...         A.foo(self)
 | |
| >>> C().foo()
 | |
| called A.foo()
 | |
| """
 | |
| 
 | |
| __test__ = {"tut1": test_1,
 | |
|             "tut2": test_2,
 | |
|             "tut3": test_3,
 | |
|             "tut4": test_4,
 | |
|             "tut5": test_5,
 | |
|             "tut6": test_6,
 | |
|             "tut7": test_7,
 | |
|             "tut8": test_8}
 | |
| 
 | |
| # Magic test name that regrtest.py invokes *after* importing this module.
 | |
| # This worms around a bootstrap problem.
 | |
| # Note that doctest and regrtest both look in sys.argv for a "-v" argument,
 | |
| # so this works as expected in both ways of running regrtest.
 | |
| def test_main(verbose=None):
 | |
|     # Obscure:  import this module as test.test_descrtut instead of as
 | |
|     # plain test_descrtut because the name of this module works its way
 | |
|     # into the doctest examples, and unless the full test.test_descrtut
 | |
|     # business is used the name can change depending on how the test is
 | |
|     # invoked.
 | |
|     from test import test_support, test_descrtut
 | |
|     test_support.run_doctest(test_descrtut, verbose)
 | |
| 
 | |
| # This part isn't needed for regrtest, but for running the test directly.
 | |
| if __name__ == "__main__":
 | |
|     test_main(1)
 |