奇怪的Python特性有哪些?
好吧,是一个 feature 还是 bug 已经搞不清了
Ubuntu 16.04.03 Python3.5.2
>>> a = ''
>>> a[1:-1]
''
>>> a[2:-1]
''
>>> a[3:-1]
''
奇怪的Python特性有哪些?
你觉得应该返回什么?
Python里确实有些特性初看挺反直觉的。我说几个自己踩过坑的:
-
可变默认参数:这估计是最经典的“坑”了。函数定义里的默认参数(比如
def foo(a=[]))只会在函数定义时被求值一次,而不是每次调用都创建新的。如果你在函数里修改了这个可变默认参数(比如a.append(1)),这个修改会一直累积,影响后续所有调用。所以,默认参数最好用不可变对象(如None),在函数体内部再初始化可变对象。 -
闭包变量绑定:在循环里创建闭包(或lambda)时,它们捕获的是变量i本身,而不是循环每一步
i的当前值。等循环结束,所有闭包看到的都是同一个i的最终值。得用默认参数把当前值“冻结”住:lambda x=i: x。 -
is和==的区别:is比较的是对象标识(内存地址),==比较的是值。对于小整数(-5到256)和短字符串,Python会缓存,所以a is b可能为True,但别依赖这个。比较值永远用==。 -
链式比较的求值顺序:像
a < b < c这样的表达式,Python会按数学直觉处理为a < b and b < c,并且中间的b只被计算一次。这很直观,但要知道它和(a < b) < c这种C语言风格的写法完全不同。 -
+=对不可变对象的作用:对列表,+=是原地修改(list.__iadd__);对元组或字符串,+=会创建一个新对象(tuple.__add__)。这可能导致a_tuple += (1,)看起来能修改元组,其实是变量a_tuple被重新赋值指向了新元组。
总结:理解这些“怪”特性,关键在明白Python的对象模型和名字绑定机制。
raise IndexError
In [457]: a='a’
In [458]: a[0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0]
Out[458]: ‘a’
> However, out of range slice indexes are handled gracefully when used for slicing:<br>>>> word[4:42]<br>'on'<br>>>> word[42:]<br>''<br>
[document]( https://docs.python.org/3.5/tutorial/introduction.html#strings)
动态语言一般倾向于默认一种行为以方便使用,而不是抛出异常,抛出异常还要处理异常多麻烦啊。动不动就抛出异常那是静态语言的习惯。
说实话,要是避免抛异常你是不是还要多写几个判断边界的语句,但是写完判断边界后你觉得是这种特性好用,还是你自己再写一堆代码好用。。
这个死循环反而很好理解啊
可以理解的,写代码起来方便
但是不抛异常可能会导致错误被隐藏起来啊
判断返回值是否空不就行了?
这大概是语言背后的哲学不同,我习惯 java 就很难理解这种 feature
一直都是这样啊
异常不一定带表错误,是否检查以及如何处理异常是程序逻辑,程序员需要根据需要使用相应的语法功能。
这就好比什么时候用 if a 什么时候用 if a is not None 是程序员的责任而不是语言的责任一样。


