简体   繁体   English

Python将变量定义为“首次使用时加载文件”

[英]Python define variable as “load file at first use”

Python beginner here. Python初学者在这里。 I currently have some code that looks like 我目前有一些看起来像的代码

a=some_file_reading_function('filea')
b=some_file_reading_function('fileb')
# ...
if some_condition(a):
    do_complicated_stuff(b)
else:
    # nothing that involves b

What itches me is that the load of 'fileb' may not be necessary, and it has some performance penalty. 让我感到困扰的是,可能不需要加载“ fileb”,并且会降低性能。 Ideally, I would load it only if b is actually required later on. 理想情况下,仅当稍后实际需要b时,我才加载它。 OTOH, b might be used multiple times, so if it is used once, it should load the file once for all. OTOH,b可能被多次使用,因此,如果使用一次,则应该一次加载该文件。 I do not know how to achieve that. 我不知道该如何实现。

In the above pseudocode, one could trivially bring the loading of 'fileb' inside the conditional loop, but in reality there are more than two files and the conditional branching is quite complex. 在上面的伪代码中,可以简单地将“ fileb”的加载带入条件循环中,但实际上有两个以上的文件,条件分支非常复杂。 Also the code is still under heavy development and the conditional branching may change. 此外,代码仍在大量开发中,条件分支可能会更改。

I looked a bit at either iterators or defining a class, but (probably due to my inexperience) could not make either work. 我稍微看了一下迭代器或定义了一个类,但是(可能由于我的经验不足)无法使它们起作用。 The key problem I met was to load the file zero times if unneeded, and only once if needed. 我遇到的关键问题是,如果不需要,将文件加载0次,如果需要,则仅加载一次。 I found nothing on searching, because "how to load a file by chunks" pollutes the results for "file lazy loading" and similar queries. 我没有在搜索中找到任何内容,因为“如何按块加载文件”会污染“文件延迟加载”和类似查询的结果。

If needed: Python 3.5 on Win7, and some_file_reading_function returns 1D- numpy.ndarray 's. 如果需要:Win7上的Python 3.5和some_file_reading_function返回1D-numpy.ndarray。

class LazyFile():
  def __init__(self, file):
    self.file = file
    self._data = None

  @property # so you can use .data instead of .data()
  def data(self):
    if self._data is None: # if not loaded
      self._data = some_file_reading_function(self.file) #load it

    return self._data

a = LazyFile('filea')
b = LazyFile('fileb')

if some_condition(a.data):
  do_complicated_stuff(b.data)
else:
  # other stuff

Actually, just found a workaround with classes. 实际上,刚刚找到了解决类的方法。 Try/except inspired by How to know if an object has an attribute in Python . 尝试/除非受如何知道对象在Python中是否具有属性的启发。 A bit ugly, but does the job: 有点丑陋,但是可以做到:

class Filecontents:
    def __init__(self,filepath):
        self.fp = filepath
    def eval(self):
        try:
            self.val
        except AttributeError:
            self.val = some_file_reading_function(self.fp)
            print(self.txt)
        finally:
            return self.val
def some_file_reading_function(fp):
    # For demonstration purposes: say that you are loading something
    print('Loading '+fp)

    # Return value
    return 0


a=Filecontents('somefile')
print('Not used yet')
print('Use #1: value={}'.format(a.eval()))
print('Use #2: value={}'.format(a.eval()))

Not sure that is the "best" (prettiest, most Pythonic) solution though. 虽然不确定这是“最佳”(最漂亮,最Pythonic)的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM