Книга: Practical Programming, Fourth Edition
Назад: Comparing Collections
Дальше: A Collection of New Information

Creating New Type Annotations

For each built-in type annotation such as int str, list, set, tuple, and dict you can specify the kind of thing it contains. To explore this, let’s revisit atoms and molecules from , using dictionaries and tuples in addition to lists.

Recall functions read_molecule and read_all_molecules; here are the headers and docstrings:

 def​ ​read_molecule​(reader: TextIO) -> list:
 """Read a single molecule from reader and return it, or return None to
  signal end of file. The first item in the result is the name of the
  compound; each list contains an atom type and the X, Y, and Z coordinates
  of that atom.
 
  >>> instring = ('COMPND TEST​​\\​​nATOM 1 N 0.1 0.2 0.3​​\\​​n' +
  'ATOM 2 N 0.2 0.1 0.0​​\\​​nEND​​\\​​n')
  >>> infile = StringIO(instring)
  >>> read_molecule(infile)
  ['TEST', ['N', '0.1', '0.2', '0.3'], ['N', '0.2', '0.1', '0.0']]
  """
 def​ ​read_all_molecules​(reader: TextIO) -> list:
 """Read zero or more molecules from reader, returning a list of the
  molecule information.
 
  >>> cmpnd1 = ('COMPND T1​​\\​​nATOM 1 N 0.1 0.2 0.3​​\\​​n' +
  'ATOM 2 N 0.2 0.1 0.0​​\\​​nEND​​\\​​n')
  >>> cmpnd2 = ('COMPND T2​​\\​​nATOM 1 A 0.1 0.2 0.3​​\\​​n' +
  'ATOM 2 A 0.2 0.1 0.0​​\\​​nEND​​\\​​n')
  >>> infile = StringIO(cmpnd1 + cmpnd2)
  >>> result = read_all_molecules(infile)
  >>> result[0]
  ['T1', ['N', '0.1', '0.2', '0.3'], ['N', '0.2', '0.1', '0.0']]
  >>> result[1]
  ['T2', ['A', '0.1', '0.2', '0.3'], ['A', '0.2', '0.1', '0.0']]
  """

Assuming that molecules have unique names, it would make sense for read_all_molecules to return a dictionary where the keys are the names of compounds and the values are the atoms.

Additionally, instead of using a four-item list for atoms, each atom will be represented as a tuple where the first item is the type of the atom and the second item is a tuple of three coordinates.

You can introduce new names for these compound types (pun unintended). Here, let’s define two new types: Atom and CompoundDict:

 Atom = tuple[str, tuple[str, str, str]]
 CompoundDict = dict[str, Atom]

They lead to the new function specifications:

 def​ ​read_molecule​(reader: TextIO) -> CompoundDict:
 """Read a single molecule from reader and return it, or return None to
  signal end of file. The returned dictionary has one key/value pair where
  the key is the name of the compound and the value is a list of Atoms.
 
  >>> instring = 'COMPND TEST​​\\​​nATOM 1 N 0.1 0.2 0.3​​\\​​n'+​​\
 'ATOM 2 N 0.2 0.1 0.0​​\\​​nEND​​\\​​n'
  >>> infile = StringIO(instring)
  >>> read_molecule(infile)
  {'TEST': [('N', ('0.1', '0.2', '0.3')), ('N', ('0.2', '0.1', '0.0'))]}
  """
 def​ ​read_all_molecules​(reader: TextIO) -> CompoundDict:
 """Read zero or more molecules from reader, returning a list of the
  molecule information.
 
  >>> cmpnd1 = 'COMPND T1​​\\​​nATOM 1 N 0.1 0.2 0.3​​\\​​n'+​​\
 'ATOM 2 N 0.2 0.1 0.0​​\\​​nEND​​\\​​n'
  >>> cmpnd2 = 'COMPND T2​​\\​​nATOM 1 A 0.1 0.2 0.3​​\\​​n'+​​\
 'ATOM 2 A 0.2 0.1 0.0​​\\​​nEND​​\\​​n'
  >>> infile = StringIO(cmpnd1 + cmpnd2)
  >>> result = read_all_molecules(infile)
  >>> result['T1']
  [('N', ('0.1', '0.2', '0.3')), ('N', ('0.2', '0.1', '0.0'))]
  >>> result['T2']
  [('A', ('0.1', '0.2', '0.3')), ('A', ('0.2', '0.1', '0.0'))]
  """
Назад: Comparing Collections
Дальше: A Collection of New Information