在Python中通过引用传递整数

时间:2013-03-01 00:45:15

标签: python function pass-by-reference pass-by-value

如何在Python中通过引用传递整数?

我想修改我传递给函数的变量的值。我已经读过Python中的所有内容都是按值传递的,但必须有一个简单的技巧。例如,在Java中,您可以传递IntegerLong等的引用类型。

  1. 如何通过引用将整数传递给函数?
  2. 最佳做法是什么?

12 个答案:

答案 0 :(得分:78)

在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.__setitem__

答案 1 :(得分:23)

您需要通过引用传递的大多数情况是您需要将多个值返回给调用者的位置。 “最佳实践”是使用多个返回值,这在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

答案 2 :(得分:5)

真的,最好的做法是退后一步,询问你是否真的需要这样做。 为什么你想要修改你传入函数的变量的值?

如果您需要快速入侵,最快的方法是传递list持有整数,并在每次使用时粘贴[0],正如mgilson的回答所示。< / p>

如果你需要为更重要的事情做一些事情,请写一个class作为属性的int,这样你就可以设置它。当然,这会迫使你为这个类提出一个好名字,对于属性 - 如果你想不出任何东西,请回去再读几遍这句话,然后使用list

更一般地说,如果你试图将一些Java习语直接移植到Python上,那你就错了。即使存在直接对应的内容(与static / @staticmethod一样),您仍然不希望在大多数Python程序中使用它,因为您在Java中使用它。

答案 3 :(得分:2)

在Python中,每个值都是一个引用(指向对象的指针),就像Java中的非基元一样。此外,与Java一样,Python只有值传递。所以,从语义上讲,它们几乎是一样的。

既然你在问题中提到了Java,我想看看你是如何在Java中实现你想要的。如果你能用Java展示它,我可以向你展示如何在Python中完全等效地完成它。

答案 4 :(得分:1)

class PassByReference:
    def Change(self, var):
        self.a = var
        print(self.a)
s=PassByReference()
s.Change(5)     

答案 5 :(得分:1)

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

答案 6 :(得分:1)

不是直接直接传递值,而是像传递值一样使用它。

x = 7
def my_method():
    nonlocal x
    x += 1
my_method()
print(x) # 8

注意事项:

  • nonlocal在python 3中引入
  • 如果封闭范围是全局范围,请使用global而不是nonlocal

答案 7 :(得分:1)

也许这不是pythonic方式,但是您可以做到

import ctypes

def incr(a):
    a += 1

x = ctypes.c_int(1) # create c-var
incr(ctypes.ctypes.byref(x)) # passing by ref

答案 8 :(得分:0)

也许比长度列表1技巧稍微更多的自我记录是旧的空类型技巧:

def inc_i(v):
    v.i += 1

x = type('', (), {})()
x.i = 7
inc_i(x)
print(x.i)

答案 9 :(得分:0)

正确的答案是使用一个类并将该值放在该类中,这使您可以完全按需传递引用。

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)

答案 10 :(得分:0)

class Obj:
  def __init__(self,a):
    self.value = a
  def sum(self, a):
    self.value += a
    
a = Obj(1)
b = a
a.sum(1)
print(a.value, b.value)// 2 2

答案 11 :(得分:-1)

在Python中,所有内容都是按值传递的,但是如果要修改某个状态,可以更改传递给方法的列表或对象中的整数值。