在函数中保存变量 - python

时间:2013-08-05 21:47:28

标签: python function save

我想一次性保存我在特定函数中创建的所有变量,以便稍后加载它们。类似的东西:

>>> def test():
      a=1
      b=2
      save.to.file(filename='file', all.variables)

>>> load.file('file')
>>> a
>>> 1

有没有办法在python中执行此操作?我知道cPickle可以做到这一点,但据我所知,必须为每个变量键入cPickle.dump(),我的脚本有几十个。此外,似乎cPickle只存储值而不存储变量的名称,因此必须记住数据最初保存的顺序。

4 个答案:

答案 0 :(得分:1)

您可以使用pickle将对象存储在文件中:

>>> a = {'a': 1, 'b': 2, 'c': 3}
>>> a
{'a': 1, 'c': 3, 'b': 2}
>>>
>>> import pickle
>>> pickle.dump(a, open('a.dump', 'wb'))
>>>
>>> a = None
>>> a
>>>
>>> a = pickle.load(open('a.dump', 'rb'))
>>> a
{'a': 1, 'c': 3, 'b': 2}
>>>

有关详情,请访问:http://docs.python.org/2/library/pickle.html

答案 1 :(得分:1)

假设您要保存的所有变量都是当前函数的本地变量,您可以通过locals函数获取它们。这几乎总是一个非常糟糕的主意,但它是可行的。

例如:

def test():
    a=1
    b=2
    pickle.dump(file, locals())

如果你print locals(),你会发现它只是一个字典,每个局部变量都有一个键。所以,当你后来load那个泡菜时,你会得到的是同样的咒语。如果你想将它注入你的本地环境,你可以......但你必须非常小心。例如,这个函数:

def test2():
    locals().update(pickle.load(file))
    print a

...将被编译为期望a是全局的而不是本地的,因此您更新本地a的事实将无效。

这只是做这件事的一个坏主意的原因之一。

那么,正确的要做什么?

最简单的说,不是拥有一大堆变量,而是只需要一个带有大量键的字典。然后你可以腌制和破坏字典,一切都是微不足道的。

或者,或者,通过使用元组明确地pickle和unpickle你想要的变量:

def test():
    a = 1
    b = 2
    pickle.dump(file, (a, b))

def test2():
    a, b = pickle.load(file)
    print a

在评论中,你说你想腌制一些或变量,跳过任何无法腌制的东西。

为了简单起见,让我们说你实际上只想挑选一个字典,跳过任何无法腌制的值。 (上面应该说明为什么这个解决方案仍然完全一般。)

那么,你怎么知道一个价值是否可以腌制?试图预测这是一个棘手的问题。即使你有一个完美的所有pickleable类型的列表,这仍然无济于事 - 一个完整的整数列表可以被腌制,但是一个完整的绑定实例方法的列表不能。

这种事情正是为什么EAFP(“容易请求宽恕而不是权限”)是像Python这样的鸭子类型语言中的一个重要原则。*找出是否可以腌制的方法是腌制它,看看你是否得到例外。

这是一个简单的演示:

def is_picklable(value):
    try:
        pickle.dumps(value)
    except TypeError:
        return False
    else:
        return True

def filter_dict_for_pickling(d):
    return {key: value for key, value in d.items() if is_picklable((key, value))}

如果将整个存储过程放在包装函数中,则可以使这一点更简洁,更有效:

def pickle_filtered_dict(d, file):
    for key, value in d.items():
        pickle.dump((key, value), file)
    except TypeError:
        pass

def pickles(file):
    try:
        while True:
            yield pickle.load(file)
    except EOFError:
        pass

def unpickle_filtered_dict(file):
    return {key: value for key, value in pickles(file)}

答案 2 :(得分:0)

您可以通过使多个变量成为对象的属性或字典中的元素来腌制多个变量。无论哪种情况,它都会保存名称。它不像在MATLAB中保存那么方便,但它总比没有好。

答案 3 :(得分:0)

如果您对pickle的API不满意,请考虑使用shelve为您提供更好的dict - 就像前端一样。

离。

>>> import shelve
>>> f = shelve.open('demo')
>>> f
<shelve.DbfilenameShelf object at 0x000000000299B9E8>
>>> list(f.keys())
['test', 'example']
>>> del f['test']
>>> del f['example']
>>> list(f.keys())
[]
>>> f['a'] = 1
>>> list(f.keys())
['a']
>>> list(f.items())
[('a', 1)]