简体   繁体   English

python将参数传递给函数

[英]python passing argument to a function

folks, i got a question about passing mutable object to a function 乡亲,我有一个关于将可变对象传递给函数的问题

with the following code, I was expecting the output to be [0,0,0], while the output is [0,1,2,3] 使用以下代码,我期望输出为[0,0,0],而输出为[0,1,2,3]

does it mean the argument is actually copied and then send to the inside of the function? 这是否意味着参数实际上已被复制,然后发送到函数内部?

def lala(a):
    n = [0, 0 , 0]
    a = n

a = [0,1,2,3]

lala(a)

print a

if i want to fulfill the above task inside the function, how shall i write it elegantly? 如果我想在函数中完成上述任务,该如何优雅地编写?

thanks very much! 非常感谢!

Python makes more sense if you think of attaching name tags to objects, rather than stuffing objects into named boxes. 如果您考虑将名称标签附加到对象,而不是将对象塞入命名框,则Python更有意义。

def lala(a):
    n = [0, 0 , 0]
    a = n

Here's what's happening. 这是正在发生的事情。

  1. You're receiving a parameter (a list in this case) and giving it the name a . 您将收到一个参数(在这种情况下为列表),并将其命名为a
  2. You're creating a new list and giving it the name n . 您正在创建一个新列表,并将其命名为n
  3. You are giving the list you named n the additional name a . 您将给您命名为n的列表附加名称a
  4. Both names, a and n , are local to the lala function, so they "expire" when the function ends. 名称an都是lala函数的本地名称,因此它们在函数结束时“过期”。
  5. The list you created in the function now has no names, and Python discards it. 您在函数中创建的列表现在没有名称,Python会丢弃它。

In other words, a is not a box into which you can put a new list. 换句话说, a不是可以在其中放入新列表的框。 It is a name you gave a list you received. 这是您给您收到的清单的名称。 Later, you reassign that name to the list you have also named n . 稍后,您将该名称重新分配给您还命名为n的列表。

Others have suggested a slice assignment, a[:] = n , which uses a reference to the items in the list rather than the list itself. 其他人建议使用切片分配a[:] = n ,该分配使用对列表中项目的引用而不是列表本身。 When you do this, the name a still points to the same list; 当您执行此操作时,名称a仍指向同一列表。 its contents have just been replaced. 它的内容刚刚被替换。 Since it is the same list that was passed into the function, any names by which it is known outside the function will "see" the new contents. 由于它是传递给该函数的相同列表,因此在函数外部已知的任何名称都将“看到”新内容。

kindall provided a great explanation in my opinion, but my preferred method for doing something like this is to have the function return the change instead of messing with references. 我认为kindall提供了一个很好的解释,但是我做这种事情的首选方法是让函数返回更改而不是弄乱引用。

def lala():
     n = [0, 0, 0]
     return n

a = [0, 1, 2, 3]

a = lala()

print a # prints [0, 0, 0]

you can use a[:] = n inside the function. 您可以在函数内部使用a[:] = n this is called a slice assignment 这称为切片分配

python does not have a call-by-reference feature. python没有按引用调用功能。 There's no general way to do this. 没有一般的方法可以做到这一点。

If you know your argument is going to be a list, and you want it to take a different value, you can write it like so: 如果您知道参数将是一个列表,并且希望它采用其他值,则可以这样编写:

def lala(a):
    a[:] = [0,0,0]

That's because a function makes new label "a" for its scope. 这是因为一个函数为其作用域添加了新标签“ a”。 Then this "a" overshadows the "a" you defined outside the function. 然后,此“ a”使您在函数外部定义的“ a”黯然失色。 So the new label a is assigned to new object [0,0,0,0] If you would write: 因此,将新标签a分配给新对象[0,0,0,0]如果要编写:

def lala(a):
    a.pop()

a = [0,1,2,3,4]
lala(a)
print(a)

You would see that a = [0,1,2,3] because pop() actually change the object which label 'a' points to. 您会看到a = [0,1,2,3],因为pop()实际上更改了标签'a'指向的对象。 (while assignment just change to what object given label points to) (而分配只是更改给定标签所指向的对象)

Note the difference between your function, and this one: 请注意您的函数与此函数之间的区别:

def lala(a):
    a[0] = 7

a = [0,1,2,3]
lala(a)
print a   # prints [7, 1, 2, 3]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM