一些有趣的Python特性—-阅读《wtfPython》记录
181214
- 看这道题
1 | >>> row = ['']*3 |
1 | '']*3 row = [ |
这个关键是board是通过一个对象row来创建的,而row对象也是通过一个对象来创建的,所以board[0],board[1],board[2],row都指向了同一列表对象
要是想只改变board[0][0]
,那就不要通过一个row对象来创建就好了
1 | '']*3 for _ in range(3)] board = [[ |
- is not… 和 is (not …)…不同
我想这个不难理解,对非空对象都能判断,主要是None对象的理解。记住下面这个就OK了
1 | 1 is (not None) |
- 字符串末尾的反斜杠
1 | 'asdf\' |
==
优先级高于not
看下这个会输出什么
1 | True == False |
1 | True == not False |
==
优先级高于not
,所以 True == not False
等同于· (True == not) False
,自然语法错误
== 和 not in 优先级同级
- 字符串的隐式连接
看下文会输出什么
1 | 'hello''' |
1 | 'hello''' |
补充
- 列表推导式中,for循环部分居然可以用
_
来占位
181215
- 布尔类型是int类型的子类
看下下面会输出什么
1 | dict = {} |
结果是spark。布尔类型是int类型的子类,所以True的整数值就是1,False是0。其次,字典中是通过判断key的哈希值是否相等来判断键是否相同的,所以1、1.0、True都是1
See this:Why is bool a subclass of int?
1 | True some_bool = |
关于isinstance()和type()用法见补充
- 类变量和类实例变量
1 | >> class A: |
首先类B、C都是A的子类,a是A的实例对象,其次要知道一点,类变量和实例变量在内部是通过类对象的 __dict__
属性来处理. 如果在当前类的字典中找不到的话就去它的父类中寻找
所以,C类给x赋值2后,C中已经有了该实例变量,但B中仍旧是用的父类A的变量。实例a也是如此
1 | class SomeClass: |
+=
回原地修改可变对象,并不改变对象,所以some的some_list不是原属性对象,another_list仍是原对象
- tuple到底可不可变
看下下面这个
1 | 1],[2],[3]) some_tuple = ([ |
不可变序列 不可变序列的对象一旦创建就不能再改变. (如果对象包含对其他对象的引用,则这些其他对象可能是可变的并且可能会被修改; 但是,由不可变对象直接引用的对象集合不能更改.)
没错,不可变的tuple确实报了错(tuple不支持修改),但是使用+=
时,确实改变了tuple
像上面说的+=
回原地修改可变对象,而tuple中+=
是两个过程,先+
再=
,所以+
操作时已经修改了原对象,但是再次赋值就触犯了元组不能修改规则,抛出异常
首先需要重温
+=
这个运算符,如a+=b
:
- 对于可变对象(mutable object)如
list
,+=
操作的结果会直接在a
对应的变量进行修改,而a
对应的地址不变.- 对于不可变对象(imutable object)如
tuple
,+=
则是等价于a = a+b
会产生新的变量,然后绑定到a
上而已.
1 | 0] a = some_tuple[ |
所以元组到底可不可变?从上面可以看到tuple不支持=
这种assign操作,但是对其中可变元素的原地修改是可以的
+=, -=, =, /=, //=, %=, *=, <<=, >>=, &=, ^=, |=
这些操作符都是原地修改可变对象,不会改变对象
所以,tuple元组的不可变是指元素对象的引用不可变,不能对其再次赋值,但是在其中可变元素对象的引用不被修改前提下,仍旧可以对可变元素对象修改
部分参考如下:
- why-does-of-a-list-within-a-python-tuple-raise-typeerror-but-modify-the-list by Stack Overflow
- Python中tuple+=赋值的四个问题
补充
- isinstance和type方法的异同
二者都可用来判断一个对象的类型,type是直接返回类型。但是isinstance方法会考虑继承的关系,会认为子类是一种父类类型,就像上面提到的True是int类型
1 | True,int) isinstance( |
isinstance(object,classinfo)
,classinfo 可以是直接或间接类名、基本类型或者由它们组成的元组
推荐使用isinstance
+=, -=, =, /=, //=, %=, *=, <<=, >>=, &=, ^=, |=
这些操作符都是原地修改可变对象,不会改变对象