File: codesfile.py

package info (click to toggle)
eccodes 2.12.0-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 480,184 kB
  • sloc: ansic: 163,815; makefile: 21,266; sh: 8,507; python: 6,026; f90: 5,762; perl: 2,891; yacc: 818; lex: 356; cpp: 305; fortran: 116; awk: 66
file content (71 lines) | stat: -rw-r--r-- 2,279 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
"""
``CodesFile`` class that implements a file that is readable by ecCodes and
closes itself and its messages when it is no longer needed.

Author: Daniel Lee, DWD, 2016
"""

from .. import eccodes
from io import IOBase

class CodesFile(IOBase):

    """
    An abstract class to specify and/or implement common behaviour that files
    read by ecCodes should implement.

    A {prod_type} file handle meant for use in a context manager.

    Individual messages can be accessed using the ``next`` method. Of course,
    it is also possible to iterate over each message in the file::

        >>> with {classname}(filename) as {alias}:
        ...     # Print number of messages in file
        ...     len({alias})
        ...     # Open all messages in file
        ...     for msg in {alias}:
        ...         print(msg[key_name])
        ...     len({alias}.open_messages)
        >>> # When the file is closed, any open messages are closed
        >>> len({alias}.open_messages)
    """

    #: Type of messages belonging to this file
    MessageClass = None

    def __init__(self, filename, mode="r"):
        """Open file and receive codes file handle."""
        #: File handle for working with actual file on disc
        #: The class holds the file it works with because ecCodes'
        # typechecking does not allow using inherited classes.
        self.file_handle = open(filename, mode)
        #: Number of message in file currently being read
        self.message = 0
        #: Open messages
        self.open_messages = []

    def __exit__(self, exception_type, exception_value, traceback):
        """Close all open messages, release file handle and close file."""
        while self.open_messages:
            self.open_messages.pop().close()
        self.file_handle.close()

    def __len__(self):
        """Return total number of messages in file."""
        return eccodes.codes_count_in_file(self.file_handle)

    def __enter__(self):
        return self

    def close(self):
        """Possibility to manually close file."""
        self.__exit__(None, None, None)

    def __iter__(self):
        return self

    def next(self):
        try:
            return self.MessageClass(self)
        except IOError:
            raise StopIteration()