我如何“冻结”一个物体,I.E。计算一次然后再引用它而不再计算它?

时间:2014-01-04 14:31:04

标签: python scope variable-assignment

我很抱歉描述不好,问题的根源是我不确定术语。

这不是一个GIS问题,而是一个普遍问题的例子:在python 2.7中,如何“冻结”一个需要花费太多时间来计算的变量,就像我对frozen_list_copy = original_list[:]一样? / p>

这里有一些代码,简化为专注于我的问题。 maketransformer()运行时间太长,它输出transformer,一个GDAL(GIS东西)坐标系转换对象,对每个循环迭代都起作用。我只需要创建一次transformer对象,然后重复调用一个方法。每次循环引用transformer变量赋值时,它都会运行maketransformer()来创建一个新变量。

def maketransformer(file): #contains arbitrary stuff that takes too long

    data = gdal.Open(file)
    output_wkt = data.GetProjection()
    srs_out = osr.SpatialReference()
    srs_out.ImportFromWkt(output_wkt)

    transformer = osr.CoordinateTransformation(srs_out)
    return transformer

transformer = maketransformer('data/w001001.adf')

for tuple in shapefilepoints:
    getelevation(transformer.Transform(tuple))

我如何只运行maketransformer()一次,然后“冻结”它产生的对象,将其与其赋值“断开连接”,这样我就可以使用该对象,而无需经历整个0.1秒的创建过程15,000次?

我想要做的是类似于:

>>> x = ['one', 'two', 'three']
>>> y = x
>>> z = x[:]     # I want to do this, but with a non-list object
>>> x[2] = 'purple'
>>> x
['one', 'two', 'purple']
>>> y
['one', 'two', 'purple']
>>> z     # So that the following happens when I use z
['one', 'two', 'three']

简而言之,我用谷歌来形容这个词是什么意思!非常感谢,为无用的特定初学者问题道歉。

编辑:我发现了一个有用的工具来发现持有的是什么:

>>>import profile
profile.run("maketransformer('data/w001001.adf')")

Profile将函数分解为其部分,返回它所做的所有事情的调用次数和时间,显示它在0.001秒内运行。问题出在其他地方。谢谢大家,教我所有这些有用的东西。

2 个答案:

答案 0 :(得分:0)

python pickle模块将从其数据占用空间(从磁盘或内存字符串)中“重建”一个对象,而无需通过初始化代码。

import pickle

...
transstr = dumps(maketransformer(...))

for ....
    getelevation(pickle.reads(transstr).Transform(tuple))

...

或其他相似的东西,我相信会做你想做的事。

答案 1 :(得分:0)

def maketransformer(file): #contains arbitrary stuff that takes too long

    data = gdal.Open(file)
    output_wkt = data.GetProjection()
    srs_out = osr.SpatialReference()
    srs_out.ImportFromWkt(output_wkt)

    transformer = osr.CoordinateTransformation(srs_out)
    return transformer

transformer = maketransformer('data/w001001.adf')

for tuple in shapefilepoints:
    getelevation(transformer.Transform(tuple))

正如您所写,此代码不会每次都重新运行maketransformermaketransformer仅运行一次,然后每个Transform调用使用相同的对象。这可能就是你所需要的。