在 Python 中通过引用传递整数[重复]
- 2025-01-03 08:41:00
- admin 原创
- 186
问题描述:
如何在 Python 中通过引用传递整数?
我想修改传递给函数的变量的值。我读到过 Python 中的所有内容都是按值传递的,但必须有一个简单的技巧。例如,在 Java 中,您可以传递引用类型Integer
、Long
等。
如何通过引用将整数传递给函数?
最佳做法是什么?
解决方案 1:
在 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__
。
解决方案 2:
大多数需要通过引用传递的情况是需要向调用者返回多个值。“最佳实践”是使用多个返回值,这在 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
解决方案 3:
并非直接传递值,而是像传递了值一样使用它。
x = 7
def my_method():
nonlocal x
x += 1
my_method()
print(x) # 8
注意事项:
nonlocal
在 Python 3 中引入如果封闭范围是全局范围,则使用
global
而不是nonlocal
。
解决方案 4:
也许这不是 Python 的方式,但你可以这样做
import ctypes
def incr(a):
a += 1
x = ctypes.c_int(1) # create c-var
incr(ctypes.ctypes.byref(x)) # passing by ref
解决方案 5:
实际上,最好的做法是退一步思考,问问自己是否真的需要这样做。为什么要修改传递给函数的变量的值?
如果您需要快速破解,最快的方法是传递一个list
保存的整数,并[0]
在每次使用它时坚持一个,正如 mgilson 的答案所示。
如果您需要为更重要的事情执行此操作,请编写一个具有属性class
的类int
,这样您就可以设置它。当然,这会迫使您为类和属性想出一个好名字——如果您想不出任何东西,请返回并再次阅读句子几次,然后使用list
。
更一般地讲,如果你试图将某些 Java 习惯用法直接移植到 Python,那么你就做错了。即使有直接对应的内容(如static
/ @staticmethod
),你仍然不想在大多数 Python 程序中使用它,因为你会在 Java 中使用它。
解决方案 6:
也许比长度为 1 的列表技巧更能自我记录的是旧的空类型技巧:
def inc_i(v):
v.i += 1
x = type('', (), {})()
x.i = 7
inc_i(x)
print(x.i)
解决方案 7:
正确的答案是使用一个类并将值放入类中,这样您就可以按照您想要的方式通过引用传递。
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)
解决方案 8:
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)
输出:
7
解决方案 9:
在 Python 中,每个值都是一个引用(指向对象的指针),就像 Java 中的非原始值一样。此外,与 Java 一样,Python 也只有按值传递。因此,从语义上讲,它们几乎相同。
既然您在问题中提到了 Java,我想看看您如何用 Java 实现您想要的功能。如果您能用 Java 演示,我就可以向您展示如何在 Python 中完全等效地实现它。
解决方案 10:
class PassByReference:
def Change(self, var):
self.a = var
print(self.a)
s=PassByReference()
s.Change(5)
解决方案 11:
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
解决方案 12:
在 Python 中,所有内容都是通过值传递的,但是如果您想修改某些状态,则可以更改传递给方法的列表或对象内的整数的值。
解决方案 13:
整数在 python 中是不可变的,一旦创建,我们就不能通过使用赋值运算符来更改变量的值,而是使其指向其他地址而不是以前的地址。
在 python 中,一个函数可以返回多个值,我们可以利用它:
def swap(a,b):
return b,a
a,b=22,55
a,b=swap(a,b)
print(a,b)
要改变变量指向的引用,我们可以将不可变数据类型(int、long、float、complex、str、bytes、truple、frozenset )包装在可变数据类型( bytearray、list、set、dict )内。
#var is an instance of dictionary type
def change(var,key,new_value):
var[key]=new_value
var =dict()
var['a']=33
change(var,'a',2625)
print(var['a'])
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理必备:盘点2024年13款好用的项目管理软件