将赋值替换为函数的方法

时间:2016-04-27 02:46:56

标签: python

我知道不可能为作为参数传递给函数的变量赋值。

>>> a = 1
>>> def foo(bar):
...     bar = 2
...
>>> foo(a)
>>> a
1

但是可以用方法修改它。

>>> a = [1, 2]
>>> def foo(bar):
...     bar.append(3)
...
>>> foo(a)
>>> a
[1, 2, 3]

但是有一种方法可以替换赋值(给变量一个全新的值)。让我的第一个例子工作的东西:

>>> a = 1
>>> def foo(bar):
...     bar.assign(2)
...
>>> foo(a)
>>> a
2

我发现的唯一选择是全局变量并设计我自己的

所以我的问题是:

  1. 有这样的方法吗? (或者替代?)

  2. 如果没有,我必须更多的是设计选择,而不是疏忽。为什么选择这个?如果有方法来修改值/内容的一部分,为什么不替换/给出全新的值/内容?

4 个答案:

答案 0 :(得分:2)

python中的所有东西都是一个对象,而python中的对象是可变的,除非它们不是。字符串,数字(int,float)等基本类型不可变,即。 1始终为1,您永远不会做出其他内容。

大多数所谓的面向对象语言实际上都是这种情况,而且更像是一种优化。

正如您所说,您需要创建自己的Object来包装不可变类型,以便改变新对象的内部。您甚至可以创建一个非常简单的类来执行此操作

class Mutatable:
    def __init__(self, value):
        self.value = value
    def assign(self, value):
        # in python you cannot overload the = (assignment) operator
        self.value = value

现在从你的例子中可以说

>>> a = Mutatable(1)
>>> def foo(bar):
...     bar.assign(2)
...
>>> foo(a)
>>> a.value
out: 2

正如其他一些海报所提到的那样。 一般编程建议。过度使用突变会导致非常难以调试的应用程序。返回值和引发异常的函数更容易测试和调试。

答案 1 :(得分:1)

首先,python中的每一个东西都是对象(除了一些单例和实习生),并且范围中存在的每个对象都包含全局,本地,内置和封闭范围。使用范围的主要目的显然是保留一组遵循特定目标的命令和脚本。

因此,通过让不同范围内的变量相互影响来销毁这种架构是不合理的。

但是在Python中为我们提供了一些工具,以便在上层范围 1 中提供一些变量,例如global语句。

注意:关于第二个例子,请记住,更改函数内的可变对象可能会影响调用者,这是因为像列表这样的可变对象实际上是指针的容器对于实际的对象,当你改变一个指针时,它将影响主对象。

<子> 1.从内到外的python中范围的层次结构是:Local,Enclosing,Global,Built-in。称为LEGB方式。

答案 2 :(得分:1)

这是两个设计决策的结果。首先,Python中的函数参数是passed by assignment。也就是说,如果你有一个像

这样的电话
foo(a)

它大致转化为

bar = a
<function body, verbatim>

这就是为什么你不能像在C中那样传递指向任何变量的指针。如果你想改变一个函数参数,它必须有一些可变的内部结构。第二个设计决策的来源是:Python中的整数是 immutable ,还有其他类型,包括其他类型的数字,字符串或元组。我不知道这个决定背后的原始动机,但我看到两个主要优势:

  • 人类更容易推理代码(当你将它传递给函数时,你可以确定你的整数不会神奇地改变)
  • 计算机更容易推理代码(出于优化或静态分析的目的),因为很多函数参数只是数字或字符串

我个人认为,你应该避免在可能的情况下改变其论点的功能。至少,它们应该是方法并改变相应的对象。否则,代码容易出错,难以维护和测试。因此,我完全支持这种不变性,并尝试在任何地方使用不可变对象。

答案 3 :(得分:1)

如果您想在没有globalreturn指令的情况下更改某个函数中的变量值,则可以在函数参数中传递其名称并使用globals()

>>> def foo(bar):
    globals()[bar] = 3      

>>> x = 7
>>> x
7
foo('x')
>>> x
3