提起Python,绝大多数同学第一印象就是“简单”。
但是,Python中也有很多有趣、微妙的事情,如果不用心去了解,很容易在开发过程中陷入误区,久久无法自拔。
下面,就介绍几个Python中有趣的事情。
1. 微妙的字符串>>> a = “wtf”
>>> b = "wtf"
>>> a is b
True
>>> a = "wtf!"
>>> b = "wtf!"
>>> a is b
False
>>> a, b = "wtf!", "wtf!"
>>> a is b
True
是不是觉得很神奇?
为什么加上!返回就是False,不加则返回True?
为什么加上!并放置同一行时,又返回True了?
- 这些行为是由于 Cpython 在编译优化时, 某些情况下会尝试使用已经存在的不可变对象而不是每次都创建一个新对象. (这种行为被称作字符串的驻留[string interning])
- 发生驻留之后, 许多变量可能指向内存中的相同字符串对象. (从而节省内存)在上面的代码中, 字符串是隐式驻留的. 何时发生隐式驻留则取决于具体的实现.
这里有一些方法可以用来猜测字符串是否会被驻留:
- 所有长度为 0 和长度为 1 的字符串都被驻留.字符串在编译时被实现 (‘wtf’ 将被驻留, 但是 ‘’.join([‘w’, ‘t’, ‘f’]) 将不会被驻留)字符串中只包含字母,数字或下划线时将会驻留. 所以 ‘wtf!’ 由于包含 ! 而未被驻留.
- 当在同一行将 a 和 b 的值设置为 “wtf!” 的时候, Python 解释器会创建一个新对象, 然后同时引用第二个变量。
- 如果你在不同的行上进行赋值操作, 它就不会“知道”已经有一个 wtf! 对象 (因为 “wtf!” 不是按照上面提到的方式被隐式驻留的). 它是一种编译器优化, 特别适用于交互式环境.
2. is和==的区别>>> a = 256
>>> b = 256
>>> a is b
True
>>> a = 257
>>> b = 257
>>> a is b
False
>>> a = 257; b = 257
>>> a is b
True
is 运算符检查两个运算对象是否引用自同一对象 (即, 它检查两个运算对象是否相同).
== 运算符比较两个运算对象的值是否相等.
- 因此is代表引用相同,==代表值相等.
下面的例子可以很好的说明这点
>>> [] == []
True
>>> [] is [] # 这两个空列表位于不同的内存地址.
False
- 256 是一个已经存在的对象, 而 257 不是
- 当你启动Python 的时候, 数值为 -5 到 256 的对象就已经被分配好了.
- 这些数字因为经常被使用, 所以会被提前准备好.Python 通过这种创建小整数池的方式来避免小整数频繁的申请和销毁内存空间.
3. is not … 不是 is (not …)
>>> 'something' is not None
True
>>> 'something' is (not None)
False
is not 是个单独的二元运算符, 与分别使用 is 和 not 不同.如果操作符两侧的变量指向同一个对象, 则 is not 的结果为 False, 否则结果为 True.
4. 逗号
>>> def f(x, y,):
... print(x, y)
...
>>> def g(x=4, y=5,):
... print(x, y)
...
>>> def h(x, **kwargs,):
File "<stdin>", line 1
def h(x, **kwargs,):
^
SyntaxError: invalid syntax
>>> def h(*args,):
File "<stdin>", line 1
def h(*args,):
^
SyntaxError: invalid syntax
在Python函数的形式参数列表中, 尾随逗号并不一定是合法的. 在Python中, 参数列表部分用前置逗号定义, 部分用尾随逗号定义.
这种冲突导致逗号被夹在中间, 没有规则定义它. (译:这一句看得我也很懵逼,只能强翻了.详细解释看下面的讨论帖会一目了然.)
5. 真亦假
True = False
if True == False:
print("I've lost faith in truth!")
输出:
I've lost faith in truth!
最初, Python 并没有 bool 型 (人们用0表示假值, 用非零值比如1作为真值).
后来他们添加了 True, False, 和 bool 型, 但是, 为了向后兼容, 他们没法把 True 和 False 设置为常量, 只是设置成了内置变量.
Python 3 由于不再需要向后兼容, 终于可以修复这个问题了, 所以这个例子无法在 Python 3.x 中执行!
python学习
学Python的伙伴,欢迎加入新的交流【君羊】:905229245
一起探讨编程知识,成为大神,群里还有软件安装包,实战案例、学习资料