python 深入变量和引用对象

简介: 变量和对象在《learning python》中的一个观点:变量无类型,对象有类型在python中,如果要使用一个变量,不需要提前声明,只需要在用的时候,给这个变量赋值即可。

变量和对象

在《learning python》中的一个观点:变量无类型,对象有类型

在python中,如果要使用一个变量,不需要提前声明,只需要在用的时候,给这个变量赋值即可。这里特别强调,只要用一个变量,就要给这个变量赋值。

所以,像这样是不行的。

>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined

反复提醒:一定要注意看报错信息。如果光光地写一个变量,而没有赋值,那么python认为这个变量没有定义。赋值,不仅仅是给一个非空的值,也可以给一个空值,如下,都是允许的

>>> x = 3
>>> lst = []
>>> word = ""
>>> my_dict = {}

img_d4d06982a0c8180bdd8c315cf1bfbc6f.png
image.png

看到上面的图了吧,从图中就比较鲜明的表示了变量和对象的关系。所以,严格地将,只有放在内存空间中的对象(也就是数据)才有类型,而变量是没有类型的。

同一个变量可以同时指向两个对象吗?

>>> x = 4
>>> x = 5
>>> x
5

变量x先指向了对象4,然后指向对象5,自动跟第一个对象4解除关系。再看x,引用的对象就是5了。那么4呢?一旦没有变量引用它了,便成了垃圾,python有一个自动的收回机制。
例如:

>>> a = 100         #完成了变量a对内存空间中的对象100的引用

img_0f3130e1312cdf1e2e2c509e07b85a33.png
image.png

然后,又操作了:

>>> a = "hello"

如下图所示:

img_9c8df5f549c223b62634a76194fb6cca.png
image.png

原来内存中的那个100就做为垃圾被收集了。而且,这个收集过程是python自动完成的,不用我们操心。

那么,python是怎么进行垃圾收集的呢?在Quora上也有人问这个问题,我看那个回答很精彩,做个链接:Python (programming language): How does garbage collection in Python work?

is和==的效果

以上过程的原理搞清楚了,下面就可以深入一步了。

>>> l1 = [1,2,3]
>>> l2 = l1

这个操作中,l1和l2两个变量,引用的是一个对象,都是[1,2,3]。何以见得?如果通过l1来修改[1,2,3],l2引用对象也修改了,那么就证实这个观点了。

>>> l1[0] = 99      #把对象变为[99,2,3]
>>> l1              #变了
[99, 2, 3]
>>> l2             #真的变了吔
[99, 2, 3]

再换一个方式:

>>> l1 = [1,2,3]
>>> l2 = [1,2,3]
>>> l1[0] = 99
>>> l1
[99, 2, 3]
>>> l2
[1, 2, 3]

l1和l2貌似指向了同样的一个对象[1,2,3],其实,在内存中,这是两块东西,互不相关。只是在内容上一样。所以,当通过l1修改引用对象的后,l2没有变化。

进一步还能这么检验:

>>> l1
[1, 2, 3]
>>> l2
[1, 2, 3]
>>> l1 == l2    #两个相等,是指内容一样
True
>>> l1 is l2    #is 是比较两个引用对象在内存中的地址是不是一样
False          #前面的检验已经说明,这是两个东东

>>> l3 = l1   #顺便看看如果这样,l3和l1应用同一个对象
>>> l3
[1, 2, 3]
>>> l3 == l1
True
>>> l3 is l1    #is的结果是True
True

某些对象,有copy函数,通过这个函数得到的对象,是一个新的还是引用到同一个对象呢?
实验:

>>> l1
[1, 2, 3]
>>> l2 = l1[:]
>>> l2
[1, 2, 3]
>>> l1[0] = 22
>>> l1
[22, 2, 3]
>>> l2
[1, 2, 3]

>>> adict = {"name":"hiekay","web":"hiekay.github.io"}
>>> bdict = adict.copy()
>>> bdict
{'web': 'hiekay.github.io', 'name': 'hiekay'}
>>> adict["email"] = "hiekay@gmail.com"
>>> adict
{'web': 'hiekay.github.io', 'name': 'hiekay', 'email': 'hiekay@gmail.com'}
>>> bdict
{'web': 'hiekay.github.io', 'name': 'hiekay'}

不过,python不总按照前面说的方式,比如小数字的时候

>>> x = 2
>>> y = 2
>>> x is y
True
>>> x = 200000
>>> y = 200000
>>> x is y      #什么道理呀,小数字的时候,就用缓存中的.
False

>>> x = 'hello'
>>> y = 'hello'
>>> x is y
True
>>> x = "what is you name?"
>>> y = "what is you name?"
>>> x is y      #不光小的数字,短的字符串也是
False

赋值是不是简单地就是等号呢?从上面得出来,=的作用就是让变量指针指向某个对象。

目录
相关文章
|
1天前
|
Shell Python
python 和shell 变量互相传递
python 和shell 变量互相传递
24 0
|
1天前
|
Python
【Python操作基础】——变量操作
【Python操作基础】——变量操作
|
1天前
|
Python
在Python中,全局变量和局部变量是两种不同类型的变量
【5月更文挑战第10天】Python中的全局变量在函数外部定义,作用域覆盖整个程序,生命周期从开始到结束。局部变量仅限于函数内部,生命周期从调用到返回。在函数内修改全局变量需用`global`关键字声明,否则会创建局部变量。
19 3
|
1天前
|
存储 安全 Java
Python中的引用和赋值机制允许变量引用内存中的对象,并通过引用计数来管理对象的生命周期
【5月更文挑战第14天】Python中的变量是对象引用,不存储数据,而是在内存中创建对象。赋值操作创建新变量并使其指向已有对象。引用计数用于管理对象生命周期,引用数为0时对象被回收。理解这些机制对编写高效Python代码很重要。
16 6
|
1天前
|
C++ Python
Python中的类与对象
Python中的类与对象
6 1
|
1天前
|
Python
python 变量的定义和使用详解
python 变量的定义和使用详解
12 0
|
1天前
|
Java C# 开发者
Python 中的类型注解是一种用于描述变量、函数参数和返回值预期类型的机制
【5月更文挑战第8天】Python的类型注解提升代码可读性和可维护性,虽非强制,但利于静态类型检查(如Mypy)。包括:变量注解、函数参数和返回值注解,使用内置或`typing`模块的复杂类型,自定义类型注解,以及泛型模拟。类型注解可在变量声明、函数定义和注释中使用,帮助避免类型错误,提高开发效率。
21 6
|
1天前
|
Python
python变量未定义(NameError)
【5月更文挑战第1天】
19 1
|
1天前
|
Python
python函数的返回值、嵌套方式以及函数中的变量(二)
python函数的返回值、嵌套方式以及函数中的变量(二)
102 1
|
1天前
|
存储 Python 容器
python函数的返回值、嵌套方式以及函数中的变量(一)
python函数的返回值、嵌套方式以及函数中的变量(一)