在Python中通过引用传递整数
在Python中如何通过引用传递整数 我想修改传递给函数的变量的值。我已经读到Python中的所有内容都是按值传递的,但必须有一个简单的技巧。例如,在Java中,您可以传递在Python中通过引用传递整数,python,function,pass-by-reference,pass-by-value,Python,Function,Pass By Reference,Pass By Value,在Python中如何通过引用传递整数 我想修改传递给函数的变量的值。我已经读到Python中的所有内容都是按值传递的,但必须有一个简单的技巧。例如,在Java中,您可以传递Integer、Long等引用类型 如何通过引用将整数传递到函数中 最佳实践是什么 在Python中,所有内容都是按值传递的,但是如果要修改某些状态,可以更改传递给方法的列表或对象中的整数值。在Python中,这种方式不太管用。Python将引用传递给对象。在你的函数中有一个对象——你可以自由地改变这个对象(如果可能的话)。但
Integer
、Long
等引用类型
在Python中,所有内容都是按值传递的,但是如果要修改某些状态,可以更改传递给方法的列表或对象中的整数值。在Python中,这种方式不太管用。Python将引用传递给对象。在你的函数中有一个对象——你可以自由地改变这个对象(如果可能的话)。但是,整数是不可变的。一种解决方法是将整数传递到一个可以变异的容器中:
def change(x):
x[0] = 3
x = [1]
change(x)
print x
这充其量是丑陋/笨拙的,但在Python中你不会做得更好。原因是在Python中,赋值(=
)会获取右侧结果的任何对象,并将其绑定到左侧的任何对象*(或将其传递给相应的函数)
理解了这一点,我们可以理解为什么没有办法改变函数中不可变对象的值——你不能改变它的任何属性,因为它是不可变的,你不能仅仅给“变量”赋值,因为你实际上在创建一个新对象(与旧对象不同)并将旧对象在本地名称空间中的名称赋予它
通常,解决方法是简单地返回所需的对象:
def multiply_by_2(x):
return 2*x
x = 1
x = multiply_by_2(x)
*在上面的第一个示例中,
3
实际上被传递到x.\uuuuu setitem\uuuuu
实际上,最好的做法是后退一步,询问您是否真的需要这样做。为什么要修改传递给函数的变量的值
如果您需要快速破解,最快的方法是传递一个包含整数的列表,并在每次使用它时都贴上一个[0]
,正如mgilson的回答所示
如果你需要做一些更重要的事情,写一个类
,它有一个int
属性,这样你就可以设置它了。当然,这会迫使您为类和属性想出一个好名字,如果您想不出任何东西,请返回并再次阅读该句子几次,然后使用列表
更一般地说,如果您试图将一些Java习惯用法直接移植到Python,那么您就错了。即使有直接对应的东西(如static
/@staticmethod
),您仍然不想在大多数Python程序中使用它,因为您将在Java中使用它。在Python中,每个值都是引用(指向对象的指针),就像Java中的非原语一样。此外,与Java一样,Python只有传递值。所以,在语义上,它们几乎是一样的
既然你在问题中提到了Java,我想看看你是如何用Java实现你想要的东西的。如果您可以用Java来演示,我可以用Python来演示如何完全等效地执行此操作。大多数需要通过引用传递的情况下,您需要将多个值返回给调用方。“最佳实践”是使用多个返回值,这在Python中比在Java等语言中容易得多
下面是一个简单的例子:
def RectToPolar(x, y):
r = (x ** 2 + y ** 2) ** 0.5
theta = math.atan2(y, x)
return r, theta # return 2 things at once
r, theta = RectToPolar(3, 4) # assign 2 things at once
可能比长度列表1技巧稍微多一些的自我记录是旧的空类型技巧:
def inc_i(v):
v.i += 1
x = type('', (), {})()
x.i = 7
inc_i(x)
print(x.i)
numpy单元素数组是可变的,但在大多数情况下,可以将其作为数值python变量进行计算。因此,它是一个比单个元素列表更方便的按引用编号容器
import numpy as np
def triple_var_by_ref(x):
x[0]=x[0]*3
a=np.array([2])
triple_var_by_ref(a)
print(a+1)
输出:
3
不是直接传递值,而是像传递一样使用它
x = 7
def my_method():
nonlocal x
x += 1
my_method()
print(x) # 8
注意事项:
非本地
是在python 3中引入的
- 如果封闭范围是全局范围,请使用
global
而不是nonlocal
也许这不是蟒蛇式的方式,但你可以这样做
import ctypes
def incr(a):
a += 1
x = ctypes.c_int(1) # create c-var
incr(ctypes.ctypes.byref(x)) # passing by ref
正确的答案是,使用一个类并将值放在类中,这让您可以完全按照自己的意愿通过引用传递
class Thing:
def __init__(self,a):
self.a = a
def dosomething(ref)
ref.a += 1
t = Thing(3)
dosomething(t)
print("T is now",t.a)
Obj类:
定义初始化(self,a):
自我价值=a
定义和(自身,a):
self.value+=a
a=Obj(1)
b=a
a、 总数(1)
打印(a.value,b.value)//2
“Python传递对象。”否。Python传递引用(指向对象的指针)。@user102008——公平点。我觉得这一点的语义变得非常混乱。最终,它们也不是“指针”。至少,肯定不是像你在C
中所说的那样。(例如,它们不必取消引用)。在我的心智模型中,更容易将事物视为“名称”和“对象”。赋值将左侧的“名称”绑定到右侧的“对象”。调用函数时,传递“对象”(有效地将其绑定到函数中的一个新本地名称)。这当然是对python引用的描述,但要想对不熟悉术语的人简洁地描述它并不容易。难怪我们会对术语感到困惑。这里我们把它描述为,这里它被描述为。在其他地方,它被称为“通过引用传递”,在它的实际含义上有一个星号。。。基本上,问题在于社区还没有弄清楚如何称呼它。Python引用与Java引用完全相同。Java引用是根据指向对象的JLS指针进行的。基本上,java/python引用和C++指针在语义上都是完全的双宾语,而其他语义也没有描述。“它们不必被取消引用”嗯,
操作符只是取消对左侧的引用。
class Thing:
def __init__(self,a):
self.a = a
def dosomething(ref)
ref.a += 1
t = Thing(3)
dosomething(t)
print("T is now",t.a)