“通过任务”是什么意思?

2024-04-25 19:10:51 发布

您现在位置:Python中文网/ 问答频道 /正文

以下是我对java和python中传递的类型和参数的理解: 在java中,有原语类型和非原语类型。前者不是客体,后者是客体。 在python中,它们都是对象。在

在java中,参数是通过值传递的,因为: 原语类型被复制然后被传递,所以它们肯定是通过值传递的。非基元类型是通过引用传递的,但是引用(指针)也是值,所以它们也是通过值传递的。 在python中,唯一的区别是“基元类型”(例如,数字)不被复制,而只是作为对象。在

以公文为基础,通过赋值传递参数。“通过任务”是什么意思?java中的对象与python的工作方式相同吗?造成这种差异的原因是什么(在java中是按值传递的,在python中是通过参数传递的)? 上面有什么错误的理解吗?在


Tags: 对象类型参数方式数字差异java基础
2条回答

类似于在C#中按值传递引用类型。在

文档:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-reference-type-parameters#passing-reference-types-by-value

代码演示:

# mutable object
l = [9, 8, 7]


def createNewList(l1: list):
    # l1+[0] will create a new list object, the reference address of the local variable l1 is changed without affecting the variable l
    l1 = l1+[0]


def changeList(l1: list):
    # Add an element to the end of the list, because l1 and l refer to the same object, so l will also change
    l1.append(0)


print(l)
createNewList(l)
print(l)
changeList(l)
print(l)

# immutable object
num = 9


def changeValue(val: int):
    # int is an immutable type, and changing the val makes the val point to the new object 8, 
    # it's not change the num value
    value = 8


print(num)
changeValue(num)
print(num)

dr:Python的语义本质上是Java的语义,没有任何原语类型。在


“Passed by assignment”实际上与您所询问的不同。1其思想是传递给函数(和其他可调用函数)的参数与赋值的工作方式完全相同。在

考虑:

def f(x):
    pass
a = 3
b = a
f(a)

b = a意味着目标b(在本例中是全局命名空间中的名称)成为对a引用的任何值的引用。在

f(a)表示目标x,在本例中,为执行f而构建的帧的本地命名空间中的名称,将成为对a引用的任何值的引用。在

语义是相同的。每当一个值被分配给一个目标(它并不总是一个简单的名称,例如,lst[0] = a或{}),它遵循相同的赋值规则集,不管它是赋值语句、函数调用、as子句还是循环迭代变量,都只有一组规则。在


但总的来说,您的直觉认为Python与Java类似,但只有引用类型是准确的:您总是“通过值传递引用”。在

争论这算不算“按引用传递”还是“按值传递”是毫无意义的。试图为它想出一个没有人会争论的新的明确的名字是没有意义的。利斯科夫在三十年前发明了这个词,如果这个词没有流行起来,那么今天有人提出的任何东西都不可能做得更好。在

你了解实际的语义,这才是最重要的。在


是的,这意味着没有复制。在Java中,只复制原语值,而Python没有原语值,因此不复制任何内容。在

the only difference is that 'primitive types'(for example, numbers) are not copied, but simply taken as objects

最好把这看作是“唯一的区别在于,没有‘原始类型’(甚至不是简单的数字)”,就像你在开始时所说的那样。在


同样值得一问的是,为什么Python没有基元类型,或者Java为什么没有基元类型。2

把所有东西都“装箱”可能会很慢。在Python中添加2 + 3意味着取消对2和{}对象的引用,从中获取本机值,将它们相加,并将结果包装到新的5对象中(或者在表中查找,因为您已经有了一个5对象)。这比只加两个整数要多得多。3

虽然一个好的JIT-like-Hotspot或pypyforpython通常可以自动执行这些优化,但有时“经常”还不够好。这就是Java有本机类型的原因:在这些情况下允许您手动优化。在

相反,Python依赖于第三方库,比如Numpy,它让您只需为整个数组支付一次装箱成本,而不是每个元素一次。这使得语言更简单,但代价是需要大量的数据。4


1。据我所知,“passed by assignment”在常见问题解答中出现过几次,但实际上并没有在参考文档或术语表中使用。参考文档已经倾向于直觉而不是严格,但是FAQ,像教程一样,在这个方向上走得更远。因此,询问FAQ中的一个术语意味着什么,除了它试图理解的直观概念外,一开始可能不是一个有意义的问题。

2。这里我将忽略Java缺少操作符重载的问题。它们没有理由不为少数核心类包含特殊的语言规则,即使它们不允许你对自己的类做同样的事情——例如,Go对range这样的事情做的正是这样,人们很少抱怨。

3。…甚至比在两个30位的数组上循环,这是Python的实际操作。与装箱的成本相比,处理无限大小的“bigint”的成本很小,因此Python总是支付额外的费用a、 几乎不值得注意的成本。Python2和Java一样,也有独立的fixed和bigint类型,但几十年的经验表明,它并没有从额外的复杂性中获得任何性能优势。

4。当然,Numpy的实现远非易事。但是使用非常简单,需要使用Numpy的人比需要编写Numpy的人多得多,因此这是一个相当不错的折衷方案。

相关问题 更多 >