RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


A Developer's Guide to Python 3.0: Standard Library : Page 6

The changes to the standard library in Python 3.0 truly "clean house." The results are both more usable and less cluttered.


The collections Module

The collections module (home of dequeue and DefaultDict) has a new factory function called namedtuple. The factory creates a subclass of Python's tuple that provides access to its fields by name in addition to access by index. This is useful when dealing with nested data structures that are so easy to create in Python, such as a tuple of dictionaries that contain pairs of tuples. Here's a little snippet that defines a named tuple Alien class:

   >>> Alien = namedtuple('Alien', 'name color special_power')
   >>> et = Alien('E.T.', 'Gray', 'Healing') 
   >>> et
   Alien(name='E.T.', color='Gray', special_power='Healing')
   >>> et.name
   >>> et.color
   >>> et.special_power
You specify the list of attributes as a space-separated string (see the first line in the preceding code). This is unorthodox, but it works because spaces aren't allowed in attribute names. You can't modify the attributes of named tuples because they are read-only, just like tuples. It would be pretty useful to have a named list too, where you could modify attributes but never add or remove fields.

The zipfile Module

The zipfile module now accepts Unicode filenames. It also has two new methods: extract() and extractall() that extract a single file or the entire archive contents to a specified directory (the current directory by default). This is welcome, because I usually just want to extract a zip file's entire contents. Until now, I always had to implement the extractall() functionality myself. The ZipFile class also supports passwords now, but I couldn't get that functionality to work; I was able to extract and read files from a password-protected .zip file without providing the password.

   >>> from zipfile import ZipFile
   >>> z = ZipFile('test.zip', 'w')
   >>> z.setpassword(b'secret')
   >>> z.writestr('1.txt', '111111111111')
   >>> z.writestr('2.txt', '2222222')
   >>> z.writestr('3.txt', '33')
   >>> z.close()
   >>> z = ZipFile('test.zip', 'r')
   >>> z.extractall() # extracting WITHOUT the password
   >>> os.path.exists('1.txt')
   >>> open('1.txt').read()
   >>> open('2.txt').read()
   >>> open('3.txt').read()

The queue Module

Python 2.5 had only a Queue class—a first-in first-out (FIFO) queue implementation. Python 3.0 adds LifoQueue and PriorityQueue classes. The only difference between the queues is the order in which stored items are retrieved. The LifoQueue is last-in first-out (which happens to be the definition of a stack). The PriorityQueue always returns the lowest available value. Here are all the queues in action: the Queue returns the items in the order they were entered, the LifoQueue returns them in reversed order, and the PriorityQueue returns them sorted by value.

   >>> import queue
   >>> from queue import Queue, LifoQueue, PriorityQueue
   >>> q = Queue()
   >>> lq = LifoQueue()
   >>> pq = PriorityQueue()
   >>> for x in q, lq, pq:
   ...   for i in [1,2,3,1,2,3]:
   ...     x.put(i)
   >>> for x in q, lq, pq:
   ...   while not x.empty():
   ...     print(x.get(), end=' ')
   ...   print()
   1 2 3 1 2 3 
   3 2 1 3 2 1 
   1 1 2 2 3 3 
If you want to store objects in a PriorityQueue that are not ordered, or if you want to control the retrieval order, it's standard practice to insert pairs, where the first element is an integer priority value, and the second element is the actual object:

   >>> from queue import PriorityQueue
   >>> pq = PriorityQueue
   >>> pq.put((1, 'one'))
   >>> pq.put((2, 'two'))
   >>> pq.put((3, 'three'))
   >>> pq.put((7, 'seven'))
   >>> pq.put((6, 'six'))
   >>> pq.put((5, 'five'))
   >>> pq.put((4, 'four'))
   >>> while not pq.empty():
   ...   print(pq.get()[1], end=' ')
   one two three four five six seven

The tempfile Module

Usually, temporary files are deleted when closed. The new NamedTemporaryFile class lets you keep the file if you pass delete=False. You can access the resulting file name using the name attribute:

   >>> from tempfile import NamedTemporaryFile
   >>> with NamedTemporaryFile(delete=False) as f:
   ...   f.write(b'12345')
   >>> f
   <tempfile._TemporaryFileWrapper object at 0x663e50>
   >>> f.closed
   >>> f.name   
   >>> f = open(f.name)
   >>> f.name
   >>> f.closed
   >>> f.read()
The SpooledTemporaryFile is similar to the standard TemporaryFile, but stores its data in memory until the file size exceeds the max_size parameter or until you call the fileno() method. Spooling data to memory can be useful if you don't want to waste time on file I/O and you have enough memory for your temporary usage.

As you can see, the changes in Python 3.0 are significant. There are many small, less interesting, or less important changes to the standard library that are not mentioned here that you may want to explore on your own.

Gigi Sayfan specializes in cross-platform object-oriented programming in C/C++/C#/Python/Java with an emphasis on large-scale distributed systems. He is currently trying to build brain-inspired intelligent machines at Numenta.
Email AuthorEmail Author
Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date