Python2.7 - 将函数列表和字典传递给全局命名空间

时间:2017-03-21 22:51:56

标签: python python-2.7 list dictionary

TL; DR 如何将两种类型的数据(例如字典和列表)从函数传递到字典和全局命名空间中的列表?

我正在编写一个与我的设备交互的脚本。该脚本要求用户提供包含CSV的多个文本文件。然后将这些值放入列表和适当的字典中。

因为文件将以相同的方式处理,所以我将处理代码放在一个函数中(本着DRY的精神)。问题是,我想将所有列表条目附加到单个列表中,并将所有字典条目附加到单个字典中,无论函数运行多少次,但是,我遇到了这个问题的范围方面的问题

根据我的理解,函数驻留在本地命名空间中。因此,我无法使函数将数据附加到全局命名空间中的“主”列表和字典中(不使用“全局”变量,这当然是否定的)。

我知道我可以从函数中返回值以使数据在全局命名空间中可用,但据我所知,我只能以一种形式返回它们,例如元组,字典等。如果是这种情况,它也不适合我的需要。

我的问题是,如何将两种类型的数据(例如字典和列表)从函数传递到字典和全局命名空间中的列表?

2 个答案:

答案 0 :(得分:1)

def func():
    return [1,2], {'abc':5}

alist, dictionary = func()

print alist, dictionary
Output: [1,2] {'abc': 5}

print type(alist), type(dictionary)
Output: (type 'list') (type 'dict')

答案 1 :(得分:0)

它不是global关键字,它是no-no,它是'master'列表和全局命名空间中的字典本身。问题是你已经降低了整体灵活性(如果其他一些代码想要导入模块并管理自己的容器会怎么样)并且使代码管理不那么明显(你需要追踪触及这些容器的所有地方) 。这些是设计权衡,在您的环境中接受可能是合理的。

因为这些是容器,并且您可以从函数中的module-global命名空间读取变量(您无法重新分配它们),所以可以在不使用global关键字的情况下使用它们。请注意,您仍在使用全局变量。

my_list = []
my_dict = {}

def func():
    while True:
        filename = input("Enter csv file, or 'done'")
        if filename == 'done':
            break
        my_list.append(filename)
        # not sure what to add to dict, but you get the point

def main():
    # this adds to the global containers
    func()
    # but be careful, this adds to the global containers and skips these
    # local versions
    my_list = ['foo']
    my_dict = {'bar':'baz'}
    func() # doesn't change the local objects

您可以根据需要将容器传递给函数,从而将容器与全局命名空间分离。

def func(my_list, my_dict):
    while True:
        filename = input("Enter csv file, or 'done'")
        if filename == 'done':
            break
        my_list.append(filename)
        # not sure what to add to dict, but you get the point

def main():
    # this adds to the local containers
    my_list = ['foo']
    my_dict = {'bar':'baz'}
    func(my_list, my_dict)

您也可以开始将这些容器捆绑到您自己的类中。这更像是一个沉重的提升,因为您可能希望将更多使用这些容器的函数放入类中。

class MyContainers:

    def __init__(self):
        self.my_list = []
        self.my_dict = {}

    def func(self):
        while True:
            filename = input("Enter csv file, or 'done'")
            if filename == 'done':
                break
            self.my_list.append(filename)
            # not sure what to add to dict, but you get the point

def main():
    foo = MyContainers()
    foo.func()
    print(foo.my_list)
    print(foo.my_dict)