在 Python 中通过引用传递整数[重复]

2025-01-03 08:41:00
admin
原创
186
摘要:问题描述:如何在 Python 中通过引用传递整数?我想修改传递给函数的变量的值。我读到过 Python 中的所有内容都是按值传递的,但必须有一个简单的技巧。例如,在 Java 中,您可以传递引用类型Integer、Long等。如何通过引用将整数传递给函数?最佳做法是什么?解决方案 1:在 Python 中,...

问题描述:

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

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

  1. 如何通过引用将整数传递给函数?

  2. 最佳做法是什么?


解决方案 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'])
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   984  
  在项目管理领域,CDCP(Certified Data Center Professional)认证评审是一个至关重要的环节,它不仅验证了项目团队的专业能力,还直接关系到项目的成功与否。在这一评审过程中,沟通技巧的运用至关重要。有效的沟通不仅能够确保信息的准确传递,还能增强团队协作,提升评审效率。本文将深入探讨CDCP...
华为IPD流程   0  
  IPD(Integrated Product Development,集成产品开发)是一种以客户需求为核心、跨部门协同的产品开发模式,旨在通过高效的资源整合和流程优化,提升产品开发的成功率和市场竞争力。在IPD培训课程中,掌握关键成功因素是确保团队能够有效实施这一模式的核心。以下将从五个关键成功因素展开讨论,帮助企业和...
IPD项目流程图   0  
  华为IPD(Integrated Product Development,集成产品开发)流程是华为公司在其全球化进程中逐步构建和完善的一套高效产品开发管理体系。这一流程不仅帮助华为在技术创新和产品交付上实现了质的飞跃,还为其在全球市场中赢得了显著的竞争优势。IPD的核心在于通过跨部门协作、阶段性评审和市场需求驱动,确保...
华为IPD   0  
  华为作为全球领先的通信技术解决方案提供商,其成功的背后离不开一套成熟的管理体系——集成产品开发(IPD)。IPD不仅是一种产品开发流程,更是一种系统化的管理思想,它通过跨职能团队的协作、阶段评审机制和市场需求驱动的开发模式,帮助华为在全球市场中脱颖而出。从最初的国内市场到如今的全球化布局,华为的IPD体系在多个领域展现...
IPD管理流程   0  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用