python函数参数传递 -01

作者: 嘿嘿_小于同学 | 来源:发表于2017-03-18 11:09 被阅读167次

写在前面

对于一个马上就要进入大四面临找工作的人来说,是时候着手准备规划一下自己了。学习了快一年的Python,并将python作为第一语言入职的我,对于python的一些知识掌握还是不够,所以参考这篇https://github.com/PyCN/interview_python/blob/master/Readme.md
来对做面试前的准备,会更一些学习python比较重要的知识点。也都是自己学习人的一点笔记。

对象和变量

在python中,一切皆对象,类型属于对象变量是没有类型的,Python是一门动态语言,比如java中定义一个String类型的变量a,当我们将一个int类型的变量赋值给a时,是不允许的,但是python是允许你这样干的。
python中所有的变量都可以理解成内存中的一个对象的引用

注意:类型属于对象,但是不是变量

a = 1 # a是只想int数据类型的一个变量
b = [1] # b是指向list类型的变量

mutable和immutable

immutable是可变对象,python中为 str tuples num set None都是不可变对象。
mutable是可变对象,python中为list dict等都是可变对象

a = 1
a =2
b = [1]
b[0] = 2
分析:

a=1在内存中开辟了一块空间存放数据1,并让变量a指向了这个内存空间,当我们让a=2时,由于内存中的1对象因为不能改变,所以被抛弃,令a变量指向了一个新的对象,值是2。

对于list,因为list是一个可变对象,第一个元素变成了2,其实list所指向的数组对象的内存是没有变的,只是数组对象的第一个元素变化了。


图 1

python的函数参数的传递: 按值传递还是按引用传递?

在讨论之前我们先看几个程序:

不可变对象
>>> def change_int(a):
...     print 'got', id(a)  # 打印函数传进来的参数地址 54355232
...     a = 10
...     print 'change_in, ', id(a), id(10) # 打印修改后的a地址和10的地址比较54355040 54355040
...
>>> num = 2
>>> print 'before change', id(num)  # 修改之前地址54355232
before change 54355232
>>> change_int(num)
got 54355232
change_in,  54355040 54355040
>>> print num
2
>>> print id(num)
54355232
>>>
分析

有一个int类型对象2,变量num指向这个对象,当传递给chang_int()函数的时候,按照按值传递的方式,赋值了num的值,a这时和num指向的是同一个对象,内存地址是一样的。但是a=10的时候,就发生了变化,和上面说的一样,创建一个新的int对象,让a指向它,但是对于函数外面的num没有发生任何变化。

可变对象
>>> def change_list(a):
...     print 'got', id(a)  # 获取参数的内存 60244040
...     a[0] = 19
...     print 'change_in', id(a) # 修改了list第一个元素后的内60244040 
...
>>> our_list = [2]
>>> print 'before change', id(our_list)
before change 60244040
>>> change_list(our_list)
got 60244040
change_in 60244040 
>>> print 'after change', id(our_list), our_list
after change 60244040 [19]
>>>

当传递给cheng_list()函数的时候,变量仍然是采用按值传递的方式,赋值变量our_list的值,于是a就和our_list指向同意对象,但是list是可变对象,对a[0]操作就是对对象中的第一个元素操作,但是不会改变对象内存空间,所以修改之后打印出来的list的内存地址是和没有修改之前是一样的。

拓展

现在我们对于可变对象(list来说),不仅仅是修改一个元素这么简单,而是直接将一个列表赋值给它会怎么样?

>>> def try_change_list_reference(the_list):
...     print 'got', the_list, id(the_list) # 参数的内存地址60352840
...     the_list = ['and', 'we', 'can', 'not', 'lie'] # 将一个列表赋值给the_list
...     print 'change_in', the_list, id(the_list) # 打印赋值后的地址60244040
...
>>> our_list = ['we', 'like', 'proepr', 'English']
>>> print 'before change', our_list, id(our_list)
before change ['we', 'like', 'proepr', 'English'] 60352840
>>> try_change_list_reference(our_list)
got ['we', 'like', 'proepr', 'English'] 60352840
change_in ['and', 'we', 'can', 'not', 'lie'] 60244040
>>> print 'after change', our_list, id(our_list)
after change ['we', 'like', 'proepr', 'English'] 60352840
>>>
分析

其实这个例子和上面的改变int类型数据一样,虽然list是可变对象,但是由于the_list参数是通过传递的,当在函数内部让它指向一个新的列表时,就相当于内存中开辟了一块内存空间存放新的列表,然后将the_list变量指向这个内存空间,但是函数外面的our_list变量不受影响,仍然指向的是原来的地址空间。

补充

a = 1
b = a
a = 2
print b # b是否会对着a的变化变化呢?

答案显然是不会的。

图 2
b = a将b变量指向和a一样的地址空间,但是a = 2是重新开辟一块内存空间,并a指向它,可以b仍然指向的是1的内存空间,所以b的值是1

总结

python函数传递参数的方式是按值传递,但是要主要可变对象和不可变对象的区别。

相关文章

  • python函数参数传递 -01

    写在前面 对于一个马上就要进入大四面临找工作的人来说,是时候着手准备规划一下自己了。学习了快一年的Python,并...

  • Python函数参数传递机制(超级详细)

    Python中,函数参数由实参传递给形参的过程,是由参数传递机制来控制的。通过学习《Python函数值传递和引用传...

  • Python 向对象传入任意数量的实参

    向函数传递任意参数 我们都知道,Python 可以通过 *params 向函数传递任意多个参数。举个栗子: 得到的...

  • Python 函数的参数传递\*args和\**kwargs

    Python 函数的参数传递*args和**kwargs 参数传递机制具有值传递(int、float等值数据类型)...

  • 深入函数参数

    函数参数 Python允许具有可变长参数的函数。使用*args作为函数参数,可以将任意数量的参数传递给该参数。然后...

  • 09:函数的参数类型

    python学习day_7: 函数的参数 1、必须参数(位置参数)调用函数时根据函数定义的参数位置来传递参数。 2...

  • python 参数传递总结

    参数的传递 python中函数的参数通过赋值的方式来传递引用对象。下面总结通过总结常见的函数参数定义方式,来理解参...

  • python:函数说明

    Python: 函数参数魔法 2016-12-01 函数参数 在 Python 中,定义函数和调用函数都很简单,但...

  • python的参数传递

    一、前言 在python中,函数参数的定义和传递有以下几种方式: 在python中,参数可以按照顺序传递,在调用函...

  • 常用数据结构和算法汇总

    Python List as belowPython语言特性1 Python的函数参数传递2 Python中的元类...

网友评论

    本文标题:python函数参数传递 -01

    本文链接:https://www.haomeiwen.com/subject/rphunttx.html