Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何访问ʟʟ;函数中的全局变量?_Python_Global Variables_Shelve - Fatal编程技术网

Python 如何访问ʟʟ;函数中的全局变量?

Python 如何访问ʟʟ;函数中的全局变量?,python,global-variables,shelve,Python,Global Variables,Shelve,我试图模拟matlab加载和保存函数。我遵循这个思路: 它很聪明。但是,如果我在一个单独的模块中编写代码,并尝试导入该模块并调用该函数,那么它就无法访问全局变量 具体来说,我编写了一个happy.py,其中包含以下函数: def save(filename='tmp', globals_=None): if globals_ is None: globals_ = globals() globals() import shelve

我试图模拟
matlab
加载和保存函数。我遵循这个思路:

它很聪明。但是,如果我在一个单独的模块中编写代码,并尝试导入该模块并调用该函数,那么它就无法访问全局变量

具体来说,我编写了一个
happy.py
,其中包含以下函数:

def save(filename='tmp', globals_=None):
    if globals_ is None:
        globals_ = globals()
        
    globals()
    import shelve
    my_shelf = shelve.open(filename, 'n')
    for key, value in globals_.items():
        if not key.startswith('__'):
            try:
                my_shelf[key] = value
            except Exception:
                print('ERROR shelving: "%s"' % key)
            else:
                print('shelved: "%s"' % key)
    my_shelf.close()

def load(filename='tmp', globals_=None):
    import shelve
    my_shelf = shelve.open(filename)
    for key in my_shelf:
        globals()[key] = my_shelf[key]
    my_shelf.close()
当我尝试的时候

a = 1
b = 2
happy.save()
它不会给出save
a
b


这是因为
global()
不会提供模块外的对象吗?我该如何做我想做的事情呢?

您可以使用
检查
查看堆栈。我定义的这个愚蠢的(名称不好的函数)在从调用名称空间提取全局变量方面似乎做得不错,尽管我还没有对它进行广泛的测试。我也不确定它是否能与不同的python实现一起工作。(我提到这一点是因为
inspect.currentframe
函数肯定依赖于实现)。它似乎可以与Cpython一起工作

import inspect
def save(globals=None):
    if globals is None:
        frames = inspect.stack()
        caller_frame = frames[-1][0]
        globals = dict((k,v) for (k,v) in caller_frame.f_globals.items() if not k.startswith('__'))
    return globals


if __name__ == "__main__":
    a = 1
    b = 2
    print save()

您可以使用
inspect
查看堆栈。我定义的这个愚蠢的(名称不好的函数)在从调用名称空间提取全局变量方面似乎做得不错,尽管我还没有对它进行广泛的测试。我也不确定它是否能与不同的python实现一起工作。(我提到这一点是因为
inspect.currentframe
函数肯定依赖于实现)。它似乎可以与Cpython一起工作

import inspect
def save(globals=None):
    if globals is None:
        frames = inspect.stack()
        caller_frame = frames[-1][0]
        globals = dict((k,v) for (k,v) in caller_frame.f_globals.items() if not k.startswith('__'))
    return globals


if __name__ == "__main__":
    a = 1
    b = 2
    print save()

将此代码粘贴到控制台时,我对其没有任何问题:

>>> def save(filename='tmp',globals_=None):
...     import shelve
...     globals_ = globals_ or globals()
...     my_shelf=  shelve.open(filename, 'n')
...     for key, value in globals_.items():
...         if not key.startswith('__'):
...             try:
...                 my_shelf[key] = value
...             except Exception:
...                 print('ERROR shelving: "%s"' % key)
...             else:
...                 print('shelved: "%s"' % key)
...     my_shelf.close()
... 
>>> def load(filename='tmp',globals_=None):
...     import shelve
...     my_shelf = shelve.open(filename)
...     for key in my_shelf:
...         globals()[key]=my_shelf[key]
...     my_shelf.close()
... 
>>> a, b = 1, 2
>>> save()
shelved: "load"
shelved: "a"
shelved: "b"
shelved: "save"
然后:

>>> def save(filename='tmp',globals_=None):
...     import shelve
...     globals_ = globals_ or globals()
...     my_shelf=  shelve.open(filename, 'n')
...     for key, value in globals_.items():
...         if not key.startswith('__'):
...             try:
...                 my_shelf[key] = value
...             except Exception:
...                 print('ERROR shelving: "%s"' % key)
...             else:
...                 print('shelved: "%s"' % key)
...     my_shelf.close()
... 
>>> def load(filename='tmp',globals_=None):
...     import shelve
...     my_shelf = shelve.open(filename)
...     for key in my_shelf:
...         globals()[key]=my_shelf[key]
...     my_shelf.close()
... 
>>> load()
>>> a, b
(1, 2)
但当您将其用作模块时,它有点奇怪:

>>> from happy import *
>>> a, b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> load()
>>> a, b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> happy.a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'happy' is not defined
>>> from happy import *
>>> a, b
(1, 2)
来自happy import的
>>*
>>>a,b
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
NameError:未定义名称“a”
>>>加载()
>>>a,b
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
NameError:未定义名称“a”
>>>很高兴。a
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
NameError:未定义名称“happy”
>>>从快乐进口*
>>>a,b
(1, 2)

这里有足够的内容供您使用吗?

将此代码粘贴到控制台时,我对其没有任何问题:

>>> def save(filename='tmp',globals_=None):
...     import shelve
...     globals_ = globals_ or globals()
...     my_shelf=  shelve.open(filename, 'n')
...     for key, value in globals_.items():
...         if not key.startswith('__'):
...             try:
...                 my_shelf[key] = value
...             except Exception:
...                 print('ERROR shelving: "%s"' % key)
...             else:
...                 print('shelved: "%s"' % key)
...     my_shelf.close()
... 
>>> def load(filename='tmp',globals_=None):
...     import shelve
...     my_shelf = shelve.open(filename)
...     for key in my_shelf:
...         globals()[key]=my_shelf[key]
...     my_shelf.close()
... 
>>> a, b = 1, 2
>>> save()
shelved: "load"
shelved: "a"
shelved: "b"
shelved: "save"
然后:

>>> def save(filename='tmp',globals_=None):
...     import shelve
...     globals_ = globals_ or globals()
...     my_shelf=  shelve.open(filename, 'n')
...     for key, value in globals_.items():
...         if not key.startswith('__'):
...             try:
...                 my_shelf[key] = value
...             except Exception:
...                 print('ERROR shelving: "%s"' % key)
...             else:
...                 print('shelved: "%s"' % key)
...     my_shelf.close()
... 
>>> def load(filename='tmp',globals_=None):
...     import shelve
...     my_shelf = shelve.open(filename)
...     for key in my_shelf:
...         globals()[key]=my_shelf[key]
...     my_shelf.close()
... 
>>> load()
>>> a, b
(1, 2)
但当您将其用作模块时,它有点奇怪:

>>> from happy import *
>>> a, b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> load()
>>> a, b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> happy.a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'happy' is not defined
>>> from happy import *
>>> a, b
(1, 2)
来自happy import的
>>*
>>>a,b
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
NameError:未定义名称“a”
>>>加载()
>>>a,b
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
NameError:未定义名称“a”
>>>很高兴。a
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
NameError:未定义名称“happy”
>>>从快乐进口*
>>>a,b
(1, 2)

这里是否有足够的内容供您解决问题?

以下内容将作为一个单独的模块使用:

import shelve
import sys
import types

EXCLUDED_TYPES = (types.ModuleType,)  # Everything can't be shelved.

def save(filename='tmp', globals_=None):
    if globals_ is None:
        globals_ = sys._getframe(1).f_globals  # Caller's globals.

    with shelve.open(filename, 'n') as my_shelf:
        for key, value in globals_.items():
            if not (key.startswith('__') or isinstance(value, EXCLUDED_TYPES)):
                try:
                    my_shelf[key] = value
                except Exception as e:
                    print('ERROR shelving: "%s"' % key, 'Exception:', e)
                else:
                    print('shelved: "%s"' % key)

def load(filename='tmp', globals_=None):
    if globals_ is None:
        globals_ = sys._getframe(1).f_globals  # Caller's globals.

    with shelve.open(filename) as my_shelf:
        for key in my_shelf:
            globals_[key]=my_shelf[key]
            print('unshelved: "%s"' % key)
一般来说,我认为函数创建这样的全局变量不是一个好主意。还要注意,
load()
可能会悄悄地更改调用方命名空间中的现有值


您无法轻松保存所有全局名称空间,因为除了
\uuuu main\uuu
之外,还有一个与加载的每个模块关联。如果您确实想这样做,可以通过迭代
sys.modules

的内容来实现,以下内容将作为一个单独的模块使用:

import shelve
import sys
import types

EXCLUDED_TYPES = (types.ModuleType,)  # Everything can't be shelved.

def save(filename='tmp', globals_=None):
    if globals_ is None:
        globals_ = sys._getframe(1).f_globals  # Caller's globals.

    with shelve.open(filename, 'n') as my_shelf:
        for key, value in globals_.items():
            if not (key.startswith('__') or isinstance(value, EXCLUDED_TYPES)):
                try:
                    my_shelf[key] = value
                except Exception as e:
                    print('ERROR shelving: "%s"' % key, 'Exception:', e)
                else:
                    print('shelved: "%s"' % key)

def load(filename='tmp', globals_=None):
    if globals_ is None:
        globals_ = sys._getframe(1).f_globals  # Caller's globals.

    with shelve.open(filename) as my_shelf:
        for key in my_shelf:
            globals_[key]=my_shelf[key]
            print('unshelved: "%s"' % key)
一般来说,我认为函数创建这样的全局变量不是一个好主意。还要注意,
load()
可能会悄悄地更改调用方命名空间中的现有值


您无法轻松保存所有全局名称空间,因为除了
\uuuu main\uuu
之外,还有一个与加载的每个模块关联。如果您真的想这样做,那么可以通过迭代
sys.modules

的内容来实现。此外,
globals\uu=globals\uuuo或globals()
是个坏主意。如果有人故意传递一个空的dict作为
globals
?@mgilson:当然,我会告诉你的。但是这是在使用
shelve
和调用
globals
进行试验的范围内。只要我们在玩炸药,我认为这是一个小问题。我肯定OP知道他在做什么。而且,
globals\uu=globals\uuo或globals()
是个坏主意。如果有人故意传递一个空的dict作为
globals
?@mgilson:当然,我会告诉你的。但是这是在使用
shelve
和调用
globals
进行试验的范围内。只要我们在玩炸药,我认为这是一个小问题。我确信OP知道他在做什么。这似乎可以可靠地“保存”调用方的全局数据——但我不认为我知道如何可靠地“加载”调用方的全局数据。我所能做的最好的事情就是从“load”返回一个dict,并强制用户
globals().update(load())
,这还不算太糟糕……这似乎可以可靠地“保存”调用者的globals——但我想我不知道如何可靠地“加载”调用者的globals。我所能做的就是从“load”返回一个dict,并强制用户
globals().update(load())
,这还不算太糟糕。。。