首先,Python中一切事物皆对象,变量是对对象在内存中的存储和地址的抽象。所有的变量都可以理解是内存中一个对象的“引用”,或者,也可以看似c中void*的感觉。
创新互联公司是一家集网站建设,新乐企业网站建设,新乐品牌网站建设,网站定制,新乐网站建设报价,网络营销,网络优化,新乐网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。
python中统一都是引用传递,同时要注意类型是属于对象的,而不是变量。而对象有两种,“可更改”(mutable)与“不可更改”(immutable)对象。在python中,strings, tuples, 和numbers是不可更改的对象,而list,dict等则是可以修改的对象。
当我们写下面语句时:
Python解释器其实顺序干了两件事情:
从这里可以看出strings类型是不可变量,不可变实际上指的是不会更该字符串,比如把a = '123' 变为 a ='1234' 实际上是先创建了 “1234” 再用a去指向它。
但是,像list,dict等“可更改”的变量,他们会直接再本地更改,不会进行副本拷贝。
简言之,当在 Python 中 a = sth 应该理解为给 sth 贴上了一个标签 a。当再赋值给 a 的时候,就好象把 a 这个标签从原来的 sth 上拿下来,贴到其他对象上,建立新的"引用"。
既然Python只允许引用传递,那有没有办法可以让两个变量不再指向同一内存地址呢?
copy对于一个复杂对象的子对象并不会完全复制,什么是复杂对象的子对象呢?就比如序列里的嵌套序列,字典里的嵌套序列等都是复杂对象的子对象。对于子对象,python会把它当作一个公共镜像存储起来,所有对他的复制都被当成一个引用,所以说当其中一个引用将镜像改变了之后另一个引用使用镜像的时候镜像已经被改变了。
deepcopy的时候会将复杂对象的每一层复制一个单独的个体出来。 当然其中主要的操作还是地址问题。
当一个引用传递给函数的时候,函数自动复制一份引用,这个函数里的引用和外边的引用没有半毛关系了.所以第一个例子里函数把引用指向了一个不可变对象,当函数返回的时候,外面的引用没半毛感觉.而第二个例子就不一样了,函数内的引用指向的是可变对象,对它的操作就和定位了指针地址一样,在内存里进行修改.
引用计数
PyObject是每个对象必有的内容,其中ob_refcnt就是做为引用计数。当一个对象有新的引用时,它的ob_refcnt就会增加,当引用它的对象被删除,它的ob_refcnt就会减少.引用计数为0时,该对象生命就结束了。
优点:
缺点:
下面的例子演示了用3种方法来在外部引用函数内部定义的列表:
#返回函数内部定义的列表
def int_list1():
l=[1,2]
return l
#将函数内部列表定义成全局的
def int_list2():
global l
l=[3,4]
#将函数内部列表定义成函数的一个属性
def int_list3():
l=[5,6]
int_list3.l=l
print(int_list1())
int_list2()
print(l)
int_list3()
print(int_list3.l)
这是截图:
开头用import函数
Python中后面引用前面的代码,在开头import函数。在程序里直接使用之前写的函数代码就可以了。
python的函数参数传递是"引用传递(地址传递)"。
python中赋值语句的过程(x = 1):先申请一段内存分配给一个整型对象来存储数据1,然后让变量x去指向这个对象,实际上就是指向这段内存(这里有点和C语言中的指针类似)。
在Python中,会为每个层次生成一个符号表,里层能调用外层中的变量,而外层不能调用里层中的变量,并且当外层和里层有同名变量时,外层变量会被里层变量屏蔽掉。函数 调用 会为函数局部变量生成一个新的符号表。
局部变量:作用于该函数内部,一旦函数执行完成,该变量就被回收。
全局变量:它是在函数外部定义的,作用域是整个文件。全局变量可以直接在函数里面应用,但是如果要在函数内部改变全局变量,必须使用global关键字进行声明。
注意 :默认值在函数 定义 作用域被解析
在定义函数时,就已经执行力它的局部变量
python中不可变类型是共享内存地址的:把相同的两个不可变类型数据赋给两个不同变量a,b,a,b在内存中的地址是一样的。