Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.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_Python 3.x_Function_Variables_Global Variables - Fatal编程技术网

Python-编码风格-跨函数更改多个变量

Python-编码风格-跨函数更改多个变量,python,python-3.x,function,variables,global-variables,Python,Python 3.x,Function,Variables,Global Variables,问题:一个函数是读取配置文件并相应地设置许多变量。 其他几个函数需要这些变量中的几个来完成这项工作 最佳实践表明,全局变量是不可能的,所以我在想,有什么办法可以改变/使用函数中非局部的变量 当有很多变量需要处理时 第一个是明显的变量传递到函数,并将结果作为正常值返回 第二种方法是直接更改/使用变量,但这是一种可接受的python方法,还是仅仅是全局变量的另一种“方法” 第三种方法是将所有变量放入一个列表中,并在函数中使用该列表 在Python3中使用哪种方法是正确的(如果一种方法优于其他方法),

问题:一个函数是读取配置文件并相应地设置许多变量。 其他几个函数需要这些变量中的几个来完成这项工作

最佳实践表明,全局变量是不可能的,所以我在想,有什么办法可以改变/使用函数中非局部的变量 当有很多变量需要处理时

第一个是明显的变量传递到函数,并将结果作为正常值返回

第二种方法是直接更改/使用变量,但这是一种可接受的python方法,还是仅仅是全局变量的另一种“方法”

第三种方法是将所有变量放入一个列表中,并在函数中使用该列表

在Python3中使用哪种方法是正确的(如果一种方法优于其他方法),应该避免使用哪种方法(如果有)

是的,我确信还有其他几种方法可以做到这一点,但我目前还不知道它们:-)

e、 g.#1)

例如#2)

例如#3)


简短回答:没有通用的解决方案。每个问题都需要一种基于特定用例的利弊平衡的单独方法。您的用例是什么


最好的方法和最常见的方法是使用容器对象,例如“config”,并将其传递给所需的每个函数。然后,您可以通过
config.myfield
(如果它支持字段访问)或
config['myfield']
或类似方式访问这些变量

然而,这也不是最好的解决方案。但这是一个相对简单的问题。特别是当您需要将值(例如config)从顶级(例如CLI解析器、config解析器)传递到非常低级的功能(例如web请求处理)时

有时,在更大的框架中,这个配置/容器对象附加到每个调用实体(例如,web框架中的web
请求
);或作为全局对象提供(例如,pytest中的
request.config
);或者类似的东西

在这种情况下,框架负责以某种方式将容器对象传递到函数中。通过将这些对象保存在每线程内存中,它们还可以确保这些对象是线程安全的。并且对象是不可变的(即,如果一个请求修改它,所有并行或进一步的请求都不会看到更改)


特别是在你们的例子中,它们都是不好的(很抱歉这么说)

示例#1修改了函数局部变量,这在所有其他函数中都不可见;如果您将它们声明为全局,则它们将属于模块范围

示例#2将字段指定给函数对象(原文如此!)。您必须将main函数作为配置对象传递(坏主意)


示例#3可行,但不方便:您必须记住每个值的位置;如上文所述,将其转换为dict或带有任意字段的config对象就可以了。

简短回答:没有通用的解决方案。每个问题都需要一种基于特定用例的利弊平衡的单独方法。您的用例是什么


最好的方法和最常见的方法是使用容器对象,例如“config”,并将其传递给所需的每个函数。然后,您可以通过
config.myfield
(如果它支持字段访问)或
config['myfield']
或类似方式访问这些变量

然而,这也不是最好的解决方案。但这是一个相对简单的问题。特别是当您需要将值(例如config)从顶级(例如CLI解析器、config解析器)传递到非常低级的功能(例如web请求处理)时

有时,在更大的框架中,这个配置/容器对象附加到每个调用实体(例如,web框架中的web
请求
);或作为全局对象提供(例如,pytest中的
request.config
);或者类似的东西

在这种情况下,框架负责以某种方式将容器对象传递到函数中。通过将这些对象保存在每线程内存中,它们还可以确保这些对象是线程安全的。并且对象是不可变的(即,如果一个请求修改它,所有并行或进一步的请求都不会看到更改)


特别是在你们的例子中,它们都是不好的(很抱歉这么说)

示例#1修改了函数局部变量,这在所有其他函数中都不可见;如果您将它们声明为全局,则它们将属于模块范围

示例#2将字段指定给函数对象(原文如此!)。您必须将main函数作为配置对象传递(坏主意)


示例#3可行,但不方便:您必须记住每个值的位置;如上所述,将其转换为
dict
或具有任意字段的配置对象将完成这些操作。

使用全局变量是正确的,但这并不是最好的方法。通常,最佳实践是您在示例1中所做的。然而,在python中,在更改传递变量的函数内部的变量时,需要注意以下几点

def func1(list1, string1):
    list1.append('in func1')
    string1 = 'in func1 string'


def main():
    list1 = ['in main']
    string1 = 'main string'
    func1(list1, string1)
    print list1
    print string1
输出:

['in main', 'in func1']
main string
根据传递给函数的变量类型和使用方法,您可能会无意中更改父函数中该变量的值

def func1(list1):
    new_list = list1
    new_list.append('in func1')


def main():
    list1 = ['in main']
    func1(list1)
    print list1
经验法则是,如果传递的变量类型是(int、float、decimal、complex、bool、string、tuple、range、frozenset、bytes),那么除了返回一个新变量和一个新值之外,没有其他方法可以更改初始变量值。在这种情况下,最佳做法是在返回不同的值时,在子函数内部使用不同的变量名

如果变量是(列表
def func1(list1, string1):
    list1.append('in func1')
    string1 = 'in func1 string'


def main():
    list1 = ['in main']
    string1 = 'main string'
    func1(list1, string1)
    print list1
    print string1
['in main', 'in func1']
main string
from copy import deepcopy

def func1(list1):
    new_list = deepcopy(list1)
    new_list.append('in func1')
    return new_list


def main():
    list1 = ['in main']
    new_func_list = func1(list1)
    print list1
    print new_func_list
['in main']
['in main', 'in func1']
def func1(list1):
    new_list = list1
    new_list.append('in func1')


def main():
    list1 = ['in main']
    func1(list1)
    print list1
['in main', 'in func1']