Geçerli python oturumundaki tüm değişkenler nasıl kaydedilir?


96

Mevcut python ortamımdaki tüm değişkenleri kaydetmek istiyorum. Görünüşe göre bir seçenek 'turşu' modülünü kullanmak. Ancak bunu 2 nedenden dolayı yapmak istemiyorum:

  1. pickle.dump()Her değişken için aramalıyım
  2. Değişkenleri geri almak istediğimde, değişkenleri kaydettiğim sırayı hatırlamalı ve ardından pickle.load()her değişkeni almak için a yapmalıyım .

Tüm oturumu kaydedecek bir komut arıyorum, böylece bu kaydedilmiş oturumu yüklediğimde, tüm değişkenlerim geri yüklenir. Mümkün mü?

Düzenleme: Sanırım pickle.dump()kaydetmek istediğim her değişkeni çağırmaktan çekinmiyorum, ancak değişkenlerin kaydedildiği tam sırayı hatırlamak büyük bir kısıtlama gibi görünüyor. Bundan kaçınmak istiyorum.

Yanıtlar:


84

Raf kullanırsanız , nesnelerin turşu sırasını hatırlamanız gerekmez, çünkü shelvesize sözlük benzeri bir nesne verir:

Çalışmanızı rafa kaldırmak için:

import shelve

T='Hiya'
val=[1,2,3]

filename='/tmp/shelve.out'
my_shelf = shelve.open(filename,'n') # 'n' for new

for key in dir():
    try:
        my_shelf[key] = globals()[key]
    except TypeError:
        #
        # __builtins__, my_shelf, and imported modules can not be shelved.
        #
        print('ERROR shelving: {0}'.format(key))
my_shelf.close()

Yenilemek:

my_shelf = shelve.open(filename)
for key in my_shelf:
    globals()[key]=my_shelf[key]
my_shelf.close()

print(T)
# Hiya
print(val)
# [1, 2, 3]

4
Mükemmel. Aradığım buydu. BTW, süper komik yazınıza Bu cümleyi bulmak: :) "Çalışmanızı rafa için"
user10

3
Ve burada "turşu" nun komik olduğunu düşündüm! :) en.wikipedia.org/wiki/Inherently_funny_word
unutbu

1
Bunu yaptığımda bu cevabın çok eski olduğunu biliyorum, şu hatayı alıyorum: Çalışma PicklingError: Can't pickle <built-in function raw_input>: it's not the same object as __builtin__.raw_inputalanımda sadece 2 değişken beyan ettim. Bunu çözmek için herhangi bir fikir var mı? Bu cevaptan sonra mevcut oturumu kaydetmenin daha iyi bir yolu var mı?
cehennem

1
Raf kullanımıyla ilgili olarak yukarıda anlattığımla aynı sorunu yaşıyorum. PicklingError: Turşu yapamıyorum <'numpy.int32'> yazın: numpy.int32 ile aynı nesne değil
Pu Zhang

1
Görünüşe göre bazı yerleşik işlevler ve paketler rafa kaldırılamayacak, bu nedenle except:yerine kullanın except TypeError:. Bu, kullanıcı tanımlı değişkenleri ve çoğu nesneyi rafa kaldıracak (pandalar veri çerçeveleri benim için rafa kaldırıldı)
Nitro

65

Burada oturup globals()sözlük olarak kaydetmeyi başaramadığım için , dereotu kütüphanesini kullanarak bir seans seçebileceğinizi keşfettim.

Bu, aşağıdakiler kullanılarak yapılabilir:

import dill                            #pip install dill --user
filename = 'globalsave.pkl'
dill.dump_session(filename)

# and to load the session again:
dill.load_session(filename)

Dill'in tüm değişkenleri kaydettiğini sanmıyorum, örneğin, dill.dump_session () işlevini o işlev için yerel olan bir işlev değişkeninde çalıştırırsanız kaydedilmez.
Parsa 05

3
Bu sadece bir kapsam sorunu, sanırım gerekirse tüm yerellerinizi () globallere () ekleyebilirsiniz?
user2589273

"TypeError: Soket nesnelerini toplayamıyor" mesajı aldım
R. Cox

1
Oturumu TypeError: no default __reduce__ due to non-trivial __cinit__
sonlandırırken

Bunu denedim ve adlandırılmış dizileri kaydedemedim, ancak bu bir turşu sınırlaması olabilir.
rhody

6

İhtiyaçlarınızı karşılayabilecek çok kolay bir yol. Benim için oldukça iyi oldu:

Basitçe, Değişken Gezgini'nde (Spider'ın sağ tarafında) bu simgeye tıklayın:

Tüm değişkenleri * .spydata biçiminde kaydetme

Tüm değişkenleri veya resimleri vb. Yükleme


Dün tüm değişkenleri .spydata biçiminde kaydettim ve bugün verileri içe aktarmayı denedim. Hiçbir değişken içe aktarılmaz :(
Bharat Ram Ammu

Bu benim için çalışıyordu, ancak artık daha fazla veriye sahip olduğum için, bir Spydata dosyası yapmak yerine, artık sıfır içerik ve yüzlerce npy dosyası içeren bir turşu dosyası oluşturuyor. Bunları nasıl açarım lütfen?
R. Cox

4

Spyder çalışma alanı değişkenlerini spyderlib işlevlerini kullanarak kaydetmenin bir yolu.

#%%  Load data from .spydata file
from spyderlib.utils.iofuncs import load_dictionary

globals().update(load_dictionary(fpath)[0])
data = load_dictionary(fpath)



#%% Save data to .spydata file
from spyderlib.utils.iofuncs import save_dictionary
def variablesfilter(d):
    from spyderlib.widgets.dicteditorutils import globalsfilter
    from spyderlib.plugins.variableexplorer import VariableExplorer
    from spyderlib.baseconfig import get_conf_path, get_supported_types

    data = globals()
    settings = VariableExplorer.get_settings()

    get_supported_types()
    data = globalsfilter(data,                   
                         check_all=True,
                         filters=tuple(get_supported_types()['picklable']),
                         exclude_private=settings['exclude_private'],
                         exclude_uppercase=settings['exclude_uppercase'],
                         exclude_capitalized=settings['exclude_capitalized'],
                         exclude_unsupported=settings['exclude_unsupported'],
                         excluded_names=settings['excluded_names']+['settings','In'])
    return data

def saveglobals(filename):
    data = globalsfiltered()
    save_dictionary(data,filename)


#%%

savepath = 'test.spydata'

saveglobals(savepath) 

Sizin için işe yarayıp yaramadığını bana bildirin. David BH


"NameError: 'fpath' adı tanımlanmadı": bir şey mi unuttum?
Thomas

Bu iyi bir fikir. Aynı şey için casusun çalışma alanından ödünç almayı düşünüyordum. Ama nasıl olduğunu çözemedim. Ancak, kodunuzu tam olarak anlamadım. Lütfen bunun Spyder gibi çalıştığını ve tüm değişkenleri otomatik olarak yakaladığını söyleyebilir misiniz, yoksa kullanmak istediğim değişkenleri belirtmem gerekiyor mu?
cqcn1991

2

Yapmaya çalıştığınız şey, sürecinizi hazırda bekletmek. Bu zaten tartışıldı . Sonuç, bunu yapmaya çalışırken çözülmesi zor birkaç problemin var olduğudur. Örneğin, açık dosya tanımlayıcılarının geri yüklenmesi ile.

Programınız için serileştirme / serileştirme alt sistemini düşünmek daha iyidir. Çoğu durumda önemsiz değildir, ancak uzun vadeli perspektifte çok daha iyi bir çözümdür.

Yine de sorunu abartmış olsam da. Küresel değişkenlerinizin diktesini seçmeye çalışabilirsiniz . globals()Sözlüğe erişmek için kullanın . Varname endeksli olduğu için sipariş hakkında endişelenmenize gerek yok.


Hayır. Süreci hazırda bekletmeye çalışmıyorum. Birkaç komut dosyası ve komut çalıştırdığım etkileşimli bir python kabuğum var. Bu komutlardan bazılarının çıktılarını (değişkenlerini) kaydetmek istiyorum, böylece gelecekte çıktıya ne zaman erişime ihtiyacım olursa, bir python kabuğu çalıştırıp tüm bu değişkenleri yükleyebilirim.
user10

Öyleyse, var_name -> var_value
nkrkv sözlüğünü seçin

0

Kabul edilen cevabın işlev görmesi için özetlenmesini istiyorsanız şunları kullanabilirsiniz:

    import shelve

    def save_workspace(filename, names_of_spaces_to_save, dict_of_values_to_save):
    '''
        filename = location to save workspace.
        names_of_spaces_to_save = use dir() from parent to save all variables in previous scope.
            -dir() = return the list of names in the current local scope
        dict_of_values_to_save = use globals() or locals() to save all variables.
            -globals() = Return a dictionary representing the current global symbol table.
            This is always the dictionary of the current module (inside a function or method,
            this is the module where it is defined, not the module from which it is called).
            -locals() = Update and return a dictionary representing the current local symbol table.
            Free variables are returned by locals() when it is called in function blocks, but not in class blocks.

        Example of globals and dir():
            >>> x = 3 #note variable value and name bellow
            >>> globals()
            {'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', 'x': 3, '__doc__': None, '__package__': None}
            >>> dir()
            ['__builtins__', '__doc__', '__name__', '__package__', 'x']
    '''
    print 'save_workspace'
    print 'C_hat_bests' in names_of_spaces_to_save
    print dict_of_values_to_save
    my_shelf = shelve.open(filename,'n') # 'n' for new
    for key in names_of_spaces_to_save:
        try:
            my_shelf[key] = dict_of_values_to_save[key]
        except TypeError:
            #
            # __builtins__, my_shelf, and imported modules can not be shelved.
            #
            #print('ERROR shelving: {0}'.format(key))
            pass
    my_shelf.close()

    def load_workspace(filename, parent_globals):
        '''
            filename = location to load workspace.
            parent_globals use globals() to load the workspace saved in filename to current scope.
        '''
        my_shelf = shelve.open(filename)
        for key in my_shelf:
            parent_globals[key]=my_shelf[key]
        my_shelf.close()

an example script of using this:
import my_pkg as mp

x = 3

mp.save_workspace('a', dir(), globals())

çalışma alanını almak / yüklemek için:

import my_pkg as mp

x=1

mp.load_workspace('a', globals())

print x #print 3 for me

çalıştırdığımda işe yaradı. Ben anlamıyorum itiraf edecek dir()ve globals()emin değilim bu yüzden bazı garip uyarı olabilir eğer% 100, ancak bugüne kadar bu işin görünüyor. Yorumlar açığız :)


biraz daha araştırmadan sonra save_workspace, globallerle önerdiğim gibi ararsanız ve save_workspacebir işlevin içindeyse, doğrulanabilirleri yerel bir kapsamda kaydetmek istiyorsanız, beklendiği gibi çalışmayacaktır. Bu kullanım için locals(). Bunun nedeni, globals'ın globalleri işlevin tanımlandığı modülden alması, benim tahminimce çağrıldığı yerden değil.


0

Bunu bir metin dosyası veya CVS dosyası olarak kaydedebilirsiniz. İnsanlar, örneğin değişkenleri kaydetmek için Spyder'ı kullanıyorlar ancak bunun bilinen bir sorunu var: belirli veri türleri için yolda içe aktarılamıyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.