字符串驻留
a = 'everyday'
b = 'every' + 'day'
print(id(a) == id(b))
True
再看看这里:
>>> a = 'wxl.com'
>>> b = 'wxl' + '.com'
>>>> id(a) == id(b)
False
这咋回事?这与CPython编译优化有关,称为字符串驻留,但是驻留的字符串只能包含字母、数字或下划线。
相同值的不可变对象
>>> a[1] = '123'
>>> a[1.0] = '1234'
>>> a
{1: '1234'}
发现1: '123’的键值对消失了
这是因为具有相同值的不可变对象在python中始终具有相同的哈希值,由于存在哈希冲突,不同值的对象也可能具有相同的哈希值。
对象销毁顺序
>>> class TEST(object):
def __init__(self):
print('init')
def __del__(self):
print('del')
# 创建两个TEST()实例,使用is判断
>>> TEST() is TEST()
init
init
del
del
False
# 创建两个TEST()实例,使用id判断
>>> id(TEST()) == id(TEST())
init
del
init
del
True
调用id函数,python创建一个TEST类的实例,并使用id函数获得内存地址之后,销毁内存丢失这个对象。
当连续两次进行此操作, Python会将相同的内存地址分配给第二个对象,所以两个对象的id值是相同的。
但是is行为却与之不同,通过打印顺序就可以看到。
for
>>> for i in range(4):
print(i)
i = 20
0
1
2
3
为什么不是执行一次就退出?
按照for在python中的工作方式,i = 10并不会影响循环,range(4)生成的下一个元素就被解包,并赋值给目标列表的变量i.
认识执行时机
>>> a = [1, 4, 6]
>>> b = (x for x in a if a.count(x) > 0)
>>> list(b)
[1, 4, 6]
>>> a = [4, 6, 8]
>>> list(b)
[]
在改变a之前,b和a一样,改变之后b也变了,原因在于生成器表达式中,in子句在声明时执行,而条件子句则是在运行时执行。
所以以下代码:
>>> a = [1, 4, 6]
>>> b = (x for x in a if a.count(x) > 0)
>>> a = [4, 6, 8]
等价于:
b = (x for x in [1, 4, 6] if [4, 6, 8].count(x>0))
>>> b = (x for x in [1, 4, 6] if [4, 6, 8].count(x>0))
>>> b
<generator object <genexpr> at 0x0000027527D5F4A0>
>>> list(b)
[]