从模块返回一个字典到main



如何从模块返回python字典?

我包含了我的代码的剥离版本。

我有main.py文件运行程序,这从另一个文件import_gdb.py导入*。

from copa_import import *

def get_data(self):
gdb_path = "<some file path>"
import_gdb(gdb_path)

在导入的copa_import.py中,我在import_gdb()中构建了一个字典。

imports ...
layers = {}
def import_gdb(gdb_path):
global layers
try:
<code to make the dictionary>
layers = <dictionary>
except:
print('failed to make dictionary')
return layers

我已经分配了一个全局变量,但我假设它只能在模块内局部访问?我已经返回了layers,如何在main.py中使用/访问?

我已经在谷歌上搜索了几天,试图找到如何做到这一点的清晰解释。我可能缺乏一些基本的理解,我欢迎指教。

您不需要使用global,正如上面的注释所述。您应该可以使用正常的导入:

gdb.py

# don't put layers at the global level here and modify its value later!!! WILL cause bugs later
# Make ALL_CAPS if you want it to look like default constant but still don't modify its value
def import_gdb(gdb_path):
# dummy logic to populate layers
layers = {
'layer1': 1,
'layer2': 2,
'layer3': 3,
'layer4': 4,
'layer5': 5,
}
return layers

main.py

import gdb
layers = gdb.import_gdb('my/path')
print(layers)

输出:

{'layer1': 1, 'layer2': 2, 'layer3': 3, 'layer4': 4, 'layer5': 5}

我通常怎么做我认为你想做的事:

已经指出了,但是您要做的通常是通过从模块级函数返回字典来完成的。

# simple example
def import_gdb(gdb_path):
with open(gdb_path, 'r') as f:
layers = parse_layers_from_file(f)
return layers

现在,如果您出于某种原因想要多次调用此方法并保存该值,可以将其作为新类的方法,该方法附加到该类的字典成员。此类类型的对象将"保存"。图层到目前为止,它看起来就像你可能已经试图做你的全局变量。

# This class would let you access the aggregated dict through layers member, and
# get new layers from the import gdb method
class LayerStore:
def __init__(self):
self.layers = {}

def import_gdb(self, gdb_path):
with open(gdb_path, 'r') as f:
new_layers = parse_layers_from_file(f)
self.layers.update(new_layers)
return new_layers

奖励:为什么你所做的事情似乎不起作用

让我们稍微简化一下您的copa_import文件

#copa_import.py
layers = {"foo": "bar"}
def import_gdb(path_to_gdb):
global layers
layers = {"bar": "baz"}
return layers

并使用第一个import方法编写一个主文件,显示全局

发生的情况
# main_with_star_import.py
from copa_import import *
print("After import")
print(layers)
print("Return value from import_gdb")
print(import_gdb(""))
print("After running import_gdb")
print(layers)
print("Re-import")
from copa_import import *
print(layers)
## Output:
#After import
{'foo': 'bar'}
#Return value from import_gdb
{'bar': 'baz'}
#After running import_gdb
{'foo': 'bar'}
#Re-import
{'bar': 'baz'}

注意到我们是如何在重新导入模块后才获得更新的全局字典的吗?这是因为模块本身就是一个名称空间和对象。全局命名空间=模块级命名空间。您在上面看到的行为是因为from module import *将值写入调用该语句的作用域中的名称空间。即使你调用import_gdb方法,重新分配全局layers,你也不会看到新的值,直到你重新导入copa_import

如果我们使用不同类型的导入会怎样?

# main_with_module_import.py
import copa_import as c_i
print("After import")
print(c_i.layers)
print("Return value from import_gdb")
print(c_i.import_gdb(""))
print("After running import_gdb")
print(c_i.layers)
print("Re-import")
from copa_import import *
print(c_i.layers)
## Output
# After import
{'foo': 'bar'}
# Return value from import_gdb
{'bar': 'baz'}
# After running import_gdb
{'bar': 'baz'}
# Re-import
{'bar': 'baz'}

使用这个方法,你必须通过模块对象来访问层。当您调用import_gdb时,模块对象的layers变量的值被覆盖,因此下次访问它时,您将获得新值。

这显示了为什么使用全局变量会让使用/调试代码的人感到困惑,因为不同类型的导入有不同类型的行为。

我前面提到的方法(使用类和/或函数)更好,因为变量的作用域和如何访问它们更清晰。

最新更新