3
3
from __future__ import print_function
4
4
5
5
import functools
6
+ import contextlib
6
7
7
8
import numpy as np
8
9
9
10
from .. import Variable
11
+ from .netCDF4_ import VariableWrapper
10
12
from ..core .utils import FrozenOrderedDict , Frozen , NDArrayMixin
11
13
from ..core import indexing
12
14
@@ -21,16 +23,18 @@ def __init__(self, variable_name, datastore):
21
23
22
24
@property
23
25
def array (self ):
24
- return self .datastore .ds .variables [self .variable_name ]
26
+ with self .datastore .ensure_open ():
27
+ return VariableWrapper (self .datastore , self .variable_name )
25
28
26
29
@property
27
30
def dtype (self ):
28
31
return np .dtype (self .array .typecode ())
29
32
30
33
def __getitem__ (self , key ):
31
- if key == () and self .ndim == 0 :
32
- return self .array .get_value ()
33
- return self .array [key ]
34
+ with self .datastore .ensure_open ():
35
+ if key == () and self .ndim == 0 :
36
+ return self .array .get_value ()
37
+ return self .array [key ]
34
38
35
39
36
40
class NioDataStore (AbstractDataStore , DataStorePickleMixin ):
@@ -40,22 +44,39 @@ def __init__(self, filename, mode='r'):
40
44
import Nio
41
45
opener = functools .partial (Nio .open_file , filename , mode = mode )
42
46
self .ds = opener ()
47
+ self ._isopen = True
43
48
self ._opener = opener
44
49
self ._mode = mode
45
50
51
+ @contextlib .contextmanager
52
+ def ensure_open (self , autoclose = True ):
53
+ if not self ._isopen :
54
+ try :
55
+ self .ds = self ._opener ()
56
+ self ._isopen = True
57
+ yield
58
+ finally :
59
+ if autoclose :
60
+ self .close ()
61
+ else :
62
+ yield
63
+
46
64
def open_store_variable (self , name , var ):
47
65
data = indexing .LazilyIndexedArray (NioArrayWrapper (name , self ))
48
66
return Variable (var .dimensions , data , var .attributes )
49
67
50
68
def get_variables (self ):
51
- return FrozenOrderedDict ((k , self .open_store_variable (k , v ))
52
- for k , v in self .ds .variables .iteritems ())
69
+ with self .ensure_open ():
70
+ return FrozenOrderedDict ((k , self .open_store_variable (k , v ))
71
+ for k , v in self .ds .variables .iteritems ())
53
72
54
73
def get_attrs (self ):
55
- return Frozen (self .ds .attributes )
74
+ with self .ensure_open ():
75
+ return Frozen (self .ds .attributes )
56
76
57
77
def get_dimensions (self ):
58
- return Frozen (self .ds .dimensions )
78
+ with self .ensure_open ():
79
+ return Frozen (self .ds .dimensions )
59
80
60
81
def get_encoding (self ):
61
82
encoding = {}
@@ -64,4 +85,6 @@ def get_encoding(self):
64
85
return encoding
65
86
66
87
def close (self ):
67
- self .ds .close ()
88
+ if self ._isopen :
89
+ self .ds .close ()
90
+ self ._isopen = False
0 commit comments