在 Python 中通过引用传递整数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15148496/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Passing an integer by reference in Python
提问by CodeKingPlusPlus
How can I pass an integer by reference in Python?
如何在 Python 中通过引用传递整数?
I want to modify the value of a variable that I am passing to the function. I have read that everything in Python is pass by value, but there has to be an easy trick. For example, in Java you could pass the reference types of Integer, Long, etc.
我想修改我传递给函数的变量的值。我读过 Python 中的所有内容都是按值传递的,但必须有一个简单的技巧。例如,在Java中,你可以通过引用类型的Integer,Long等等。
- How can I pass an integer into a function by reference?
- What are the best practices?
- 如何通过引用将整数传递给函数?
- 最佳做法是什么?
采纳答案by mgilson
It doesn't quite work that way in Python. Python passes references to objects. Inside your function you have an object -- You're free to mutate that object (if possible). However, integers are immutable. One workaround is to pass the integer in a container which can be mutated:
它在 Python 中不太适用。Python 传递对对象的引用。在您的函数中,您有一个对象——您可以随意修改该对象(如果可能)。但是,整数是不可变的。一种解决方法是将整数传递到可以变异的容器中:
def change(x):
x[0] = 3
x = [1]
change(x)
print x
This is ugly/clumsy at best, but you're not going to do any better in Python. The reason is because in Python, assignment (=) takes whatever object is the result of the right hand side and binds it to whatever is on the left hand side *(or passes it to the appropriate function).
这充其量是丑陋/笨拙的,但你不会在 Python 中做得更好。原因是因为在 Python 中,赋值 ( =) 将任何对象作为右侧的结果并将其绑定到左侧的任何对象 *(或将其传递给适当的函数)。
Understanding this, we can see why there is no way to change the value of an immutable object inside a function -- you can't change any of its attributes because it's immutable, and you can't just assign the "variable" a new value because then you're actually creating a new object (which is distinct from the old one) and giving it the name that the old object had in the local namespace.
理解了这一点,我们就可以明白为什么没有办法改变函数内不可变对象的值——你不能改变它的任何属性,因为它是不可变的,你不能只为“变量”分配一个新的值,因为这样您实际上是在创建一个新对象(与旧对象不同)并为其指定旧对象在本地命名空间中的名称。
Usually the workaround is to simply returnthe object that you want:
通常解决方法是简单地返回您想要的对象:
def multiply_by_2(x):
return 2*x
x = 1
x = multiply_by_2(x)
*In the first example case above, 3actually gets passed to x.__setitem__.
*在上面的第一个示例中,3实际上被传递给x.__setitem__.
回答by recursive
In Python, everything is passed by value, but if you want to modify some state, you can change the value of an integer inside a list or object that's passed to a method.
在 Python 中,一切都是按值传递的,但是如果您想修改某个状态,则可以更改传递给方法的列表或对象中的整数值。
回答by abarnert
Really, the best practice is to step back and ask whether you really need to do this. Whydo you want to modify the value of a variable that you're passing in to the function?
真的,最好的做法是退后一步,问问你是否真的需要这样做。为什么要修改传递给函数的变量的值?
If you need to do it for a quick hack, the quickest way is to pass a listholding the integer, and stick a [0]around every use of it, as mgilson's answer demonstrates.
如果您需要快速破解,最快捷的方法是传递一个list持有整数,并[0]在每次使用它时都贴上 a ,如 mgilson 的回答所示。
If you need to do it for something more significant, write a classthat has an intas an attribute, so you can just set it. Of course this forces you to come up with a good name for the class, and for the attribute—if you can't think of anything, go back and read the sentence again a few times, and then use the list.
如果您需要为更重要的事情做这件事,请编写class具有int作为属性的 a,以便您可以设置它。当然,这迫使你为类和属性想出一个好名字——如果你想不出什么,回去再读几遍句子,然后使用list.
More generally, if you're trying to port some Java idiom directly to Python, you're doing it wrong. Even when there is something directly corresponding (as with static/@staticmethod), you still don't want to use it in most Python programs just because you'd use it in Java.
更一般地说,如果您尝试将某些 Java 习惯用法直接移植到 Python,那么您就错了。即使有直接对应的东西(如static/ @staticmethod),您仍然不想在大多数 Python 程序中使用它,因为您会在 Java 中使用它。
回答by newacct
In Python, every value is a reference (a pointer to an object), just like non-primitives in Java. Also, like Java, Python only has pass by value. So, semantically, they are pretty much the same.
在 Python 中,每个值都是一个引用(指向对象的指针),就像 Java 中的非原语一样。此外,与 Java 一样,Python 只有按值传递。因此,在语义上,它们几乎相同。
Since you mention Java in your question, I would like to see how you achieve what you want in Java. If you can show it in Java, I can show you how to do it exactly equivalently in Python.
由于您在问题中提到了 Java,我想看看您如何在 Java 中实现您想要的。如果你能用 Java 展示它,我可以向你展示如何用 Python 完全等效地做到这一点。
回答by Gabe
Most cases where you would need to pass by reference are where you need to return more than one value back to the caller. A "best practice" is to use multiple return values, which is much easier to do in Python than in languages like Java.
大多数需要通过引用传递的情况是您需要将多个值返回给调用者。“最佳实践”是使用多个返回值,这在 Python 中比在 Java 等语言中容易得多。
Here's a simple example:
这是一个简单的例子:
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
回答by shruti
class PassByReference:
def Change(self, var):
self.a = var
print(self.a)
s=PassByReference()
s.Change(5)
回答by mheyman
Maybe slightly more self-documenting than the list-of-length-1 trick is the old empty type trick:
也许比 list-of-length-1 技巧更自我记录的是旧的空类型技巧:
def inc_i(v):
v.i += 1
x = type('', (), {})()
x.i = 7
inc_i(x)
print(x.i)
回答by Trisoloriansunscreen
A numpy single-element arrayis mutable and yet for most purposes, it can be evaluated as if it was a numerical python variable. Therefore, it's a more convenient by-reference number container than a single-element list.
一个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)
output:
输出:
3
回答by Uri
Not exactly passing a value directly, but using it as if it was passed.
不完全是直接传递值,而是像传递值一样使用它。
x = 7
def my_method():
nonlocal x
x += 1
my_method()
print(x) # 8
Caveats:
注意事项:
nonlocalwas introduced in python 3- If the enclosing scope is the global one, use
globalinstead ofnonlocal.
nonlocal在python 3中引入- 如果封闭范围是全局范围,请使用
global代替nonlocal。
回答by Sergey Kovalev
Maybe it's not pythonic way, but you can do this
也许这不是pythonic方式,但你可以这样做
import ctypes
def incr(a):
a += 1
x = ctypes.c_int(1) # create c-var
incr(ctypes.ctypes.byref(x)) # passing by ref

