Pensando en los parámetros de Python

Pensando en los parámetros de Python

Perspectiva de Xiaobian DevOps

Introducción

    在群里和人讨论了有关python参数传递的机制。对方说是赋值传递,我持的观点是引用传递,讨论了许久,对方仍没讲解明白赋值传递的实现。我查看官方文档,官方文档的描述为:

Recuerde que los argumentos se pasan por asignación en Python. El resultado de cambiar el documento oficial a chino es: Recuerde que los argumentos se pasan por asignación en Python. No fui antes a los documentos oficiales, después de la discusión de hoy he hecho algunas reflexiones sobre el paso de explorar los documentos oficiales.
Versión en inglés del enlace del documento: https://docs.python.org/3/faq/programming.html#how-do-i-write-a-function-with-output-parameters-call-by-reference
Versión en chino del enlace del documento: Https://docs.python.org/zh-cn/3/faq/programming.html#how-do-i-write-a-function-with-output-parameters-call-by-reference

Pasar por valor y pasar por referencia


    值传递的方式,传入函数的参数是实际参数的复制品,不管在函数中对这个复制品如何操作,实际参数本身不会受到任何影响
     引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中所进行的修改,将影响实际参数。

Pasando los parámetros de la función python


    对于pythoner来说,在python中一切皆对象是众所周知的。对象又分为类似于数字不可变的对象和类似于字典可变的对象。
    先看下面的代码

def test(a , b) :
   a, b = b, a
  print("test函数里,a的值是", a, ";b的值是", b)
  print("test函数里,a的内存地址是", id(a), ";b的内存地址是", id(b))
a = 1
b = 2
test(a , b)
print("交换结束后,a的值是", a , ";变量b的值是", b)
print("交换结束后,a的内存地址是", id(a) , ";b的内存地址是", id(b))
       运行的结果如下

test函数里,a的值是 2 ;b的值是 1
test函数里,a的内存地址是 140705270535872 ;b的内存地址是 140705270535840
交换结束后,a的值是 1 ;变量b的值是 2
交换结束后,a的内存地址是 140705270535840 ;b的内存地址是 140705270535872
    从运行结果来看,在test函数里,a和b的值分别是2和1,交换结束后,变量a和b的值依然是1和2,并没有发生改变,程序中定义的变量a和b并不是test函数里的a和b。
    可以推测,test函数里的a和b只是主程序中变量a和b的复制品。
    代码开始只是定义了a和b两个变量,当程序运行到test函数时,进入 test函数,并将主程序中的a、b作为变量传入到test函数,此时,系统分别为主程序和test函数各分配一个栈区,用于保存各自的变量。
   将主程序中的a、b作为变量传入到test函数,实际上是在test函数栈区重新生成了两个变量a、b,并将主程序中a、b变量的值赋值给test函数栈区中的a和b,即对test函数中的a和b进行初始化。可以理解,是将a=1和b=2传递给了test函数,因此可以理解为将赋值传递给了test函数。只是在test栈区内,将test栈区内将test栈区a、b两变量所对应的内存地址交换了,但并未影响到主栈区内的a和b。

Pensando en los parámetros de Python
Mira el siguiente código


def test(d):
  d['a'], d['b'] = d['b'], d['a']
  print("test函数里,a元素的值是",d['a'], ";b元素的值是", d['b'])
  print("test函数里,a元素的内存地址是",id(['a']), ";b元素的值是", id(d['b']))

d = {'a': 1, 'b': 2}
test(d)
print("交换结束后,a元素的值是",d['a'], ";b元素的值是", d['b'])
print("交换结束后,a元素的内存地址是",id(['a']), ";b元素的值是", id(d['b']))
       运行结果如下

test函数里,a元素的值是 2 ;b元素的值是 1
test函数里,a元素的内存地址是 1612700978880 ;b元素的值是 140705270535840
交换结束后,a元素的值是 2 ;b元素的值是 1
交换结束后,a元素的内存地址是 1612700978880 ;b元素的值是 140705270535840

¿El resultado es el mismo que el de la suposición?
De hecho, lo mismo es cierto. El área de la pila principal pasa d = {'a': 1, 'b': 2} al área de la pila de prueba, pero el área de la pila de prueba usa d ['a'], d [' b '] = d [' b '], cuando se intercambia d [' a '], usa operaciones en el diccionario mismo {' a ': 1,' b ': 2}, no en el área de la pila de prueba d Operaciones realizado. El código se modifica de la siguiente manera


def test(d):
  d['a'], d['b'] = d['b'], d['a']
  print("test函数里,a元素的值是",d['a'], ";b元素的值是", d['b'])
  print("test函数里,a元素的内存地址是",id(['a']), ";b元素的值是", id(d['b']))
  d = None

d = {'a': 1, 'b': 2}
test(d)
print("交换结束后,a元素的值是",d['a'], ";b元素的值是", d['b'])
print("交换结束后,a元素的内存地址是",id(['a']), ";b元素的值是", id(d['b']))
      运行结果

```

En la función de prueba, el valor del elemento a es 2; el valor del elemento b es 1 En la
función de prueba, la dirección de memoria del elemento a es 2532485631680; el valor del elemento b es 140705270535840 Después del
intercambio, el el valor del elemento a es 2; el valor del elemento b 1
después del final del intercambio, la dirección de un elemento de memoria es 2532485631680; el elemento 140705270535840 es el valor de b

Se encuentra que {'a': 1, 'b': 2} en sí no se ha modificado.
La siguiente oración del documento oficial es Dado que la asignación solo crea referencias a objetos, no hay un alias entre el nombre de un argumento en el llamador y el destinatario de la llamada, por lo que no hay una llamada por referencia per se.

para resumir

1. No es posible dividir el paso de parámetros de una función de Python en objetos variables y objetos inmutables para ilustrar
2. El paso de parámetros de Python no se pasa por valor o por referencia, sino por asignación.
3. Utilice directamente "= "para asignar un valor. Sin efecto
4. Si desea que la función modifique los datos, puede encapsular los datos en un objeto variable. Lo
anterior es el pensamiento sobre los parámetros de Python. Corrija las deficiencias e inconvenientes.

Preguntas de pensamiento

Finalmente, se proporciona un fragmento de código:


def test(l):
   l[0] = "a"
   l = [4, 5, 6]

l = [1, 2, 3]
test(l)
print(l)

¿Cuál es el resultado de la operación?
En primer lugar, no lo ejecute. Primero prediga el resultado de la ejecución, publique el resultado previsto en el área de mensajes y luego ejecútelo para ver si coincide con el resultado previsto.

Supongo que te gusta

Origin blog.51cto.com/15127511/2657825
Recomendado
Clasificación