参考书:《Python疯狂讲义》、《Python学习手册(第4版)》、菜鸟教程等
1 Python 单行运行、多行运行问题
(1)在使用pycharm时,整个py文件运行很简单,但想运行函数内的单行、类内的单行,建议 *** 作:
- 选择局部代码进行运行;
- 选中需要运行的代码;
- 右键,选择Execute Selection in Console,即可运行。
(2)在命令行窗口下时,单行运行正常 *** 作;但想运行函数/多行运行,建议使用;\
。以下举个例子。
(3)为什么是使用;\
呀?
这是因为命令窗口下使用;
可以让Python解释器识别出这一行代码结束
,表示分隔代码的意思。而\
为转义字符,这里可以让Python解释器知道要交互的代码块还没有结束。
2 可变对象和不可变对象
-
不可变对象(变量指向的内存的中的值不能够被改变):
当更改该对象时,由于所指向的内存中的值不可改变,所以会把原来的值复制到新的空间,然后变量指向这个新的地址
。python中数值类型(int、float),布尔型 bool,字符串 str,元组 tuple 都是不可变对象。 -
可变对象(变量指向的内存的中的值能够被改变):
当更改该对象时,所指向的内存中的值直接改变,没有发生复制行为
。python中列表 list,字典 dict,集合 set都是可变对象。包括自定义的类对象也是可变对象。 -
python变量保存的是对象的引用,这个引用指向堆内存里的对象,在堆中分配的对象分为两类,一类是可变对象,一类是不可变对象。不可变对象的内容不可改变,保证了数据的不可修改(安全,防止出错),同时可以使得在多线程读取的时候不需要加锁。
() is () # 返回True,因为tuple是不可变对象(不可改变)
'' is '' # 返回True,因为str是不可变对象
None is None # 返回True,None也是不可变的
[] is [] # 返回False,因为是可变对象(可能改变,定义出来的两个必然要不一样)
{} is {} # 返回False,因为是可变对象
[] == [] # 返回True,注意==和is的不同,==只比较内容,is比较地址(id)
class Student:
pass
Student() is Student() # 返回False,自定义类型也是可变对象,两次定义的对象地址是不同的
id(Student()) == id(Student()) # 返回True,这里比较神奇。这是因为创建一个Student对象,id()后返回地址但是进行了对象销毁,第二次又重新创建,两次占用了同一个地址
3 Python不可变对象的编译时驻留
(类似java的常量池)
使用java的开发者、学习者,可以回忆回忆JVM的常量池
int 的驻留:-5到256之间的整数都会进行驻留,再次定义的变量地址不变,为什么是-5到256呢,这是解释器决定的,依赖于具体实现。str的驻留:只包含字母,数字,下划线的字符串会驻留;长度为0或1的会驻留;
a = -5
b = -5
a is b
# True,-5到256之间的整数,驻留(因为这部分数据会频繁调用,驻留可以节省资源)
r
a = 256
b = 256
a is b
# True,-5到256之间的整数,驻留
a = -6
b = -6
a is b
# False,非-5到256之间的整数,不驻留
a = 257
b = 257
a is b
# False,非-5到256之间的整数,不驻留
a = 'hello_world'
b = 'hello'+'_'+'world'
a is b
# True,只包含字母,数字,下划线的字符串会驻留
a = 'hello_world!'
b = 'hello_world!'
a is b
# False,包含了特殊字符!, 不驻留
'hello_world' is '_'.join(['hello', 'world'])
# False,因为驻留是编译阶段发生的,join在解释阶段才产生结果,未进行驻留
a, b = 'hello_world!', 'hello_world!'
a is b
# True 编译器的优化,在同一行赋值字符串时,只创建一个对象,指给两个引用。
#(ps:不适用3.7.x以下版本,3.7.x以下中会返回False,建议使用Python3.8.x)
4 关于Python 驻留的坑 4.1 Python 驻留的现象
跟驻留没有直接关系,是(1)命令行窗口单行交互式、(2)命令行窗口函数式、(3).py文件内;这3种情况。
(1)既然python的整型-5到256之间的整数都会进行驻留,非-5到256之间的整数不驻留,且其目的是为了提高效率。那么就这里开始探索:
可以看出在
(1)命令行窗口单行交互式
中-5到256之间的整数都会进行驻留,其(-5到256)之外为False, 被显示出来。
可以看出在
(2)命令行窗口函数式
中-5到256之间的整数都会进行驻留,其之外为True,也没有被显示出来
这里用了菜鸟的在线编译,而Pycharm的如下:
# 将函数放进.py文件里面结果为True
def func():
a = 257
b = 257
return a is b
func()
# 返回True
4.2 出现Python 驻留的坑的原因可以看出在
(3).py文件内
中-5到256之间的整数都会进行驻留,其之外为True,也没有被显示出来
-
在命名行窗口下运行代码,是交互式,而且是一行一行解释,但for、while、函数调用等一起解释,形成的机器指令可以简单理解为一体。
-
是python的代码块机制导致的。在同一代码块中相同值的赋值会指向同一个对象。函数体,类对象体,py文件,模块都可以看作一个代码块,导致在命令行窗口单行交互式下跟命令行窗口函数式、py文件内不一样。
-
在交互式命令行上,一行看作一个代码块,所以,这里所谓“代码块的优化”,就是前面提到的,同行赋值的优化,只在一行(代码块)上优化。
-
到具体直接运行py文件,又有了更大范围的代码块的优化,所以连着两行相同赋值的对象,会指向同一个对象。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)