知识点

本篇文章主要总结一些 python 的小知识点
----- 来自 《流畅的 Python》 一书

  • in 和 for i in 的机制
a = [1,2,3,4,5,6,7]
for i in a:
    print i
# 这里 for in 的机制是判断 i = a[0], i = a[1], .......
if 5 in a:
  print "5 in a"
# 这里的 in 机制是判断 5 == a[0], 5 == a[1], ......
  • random 的 choice
from random import choice
a = [1,2,3,4,5,6,7]
choice(a)
# 随机返回序列中的一个值
# 注意参数必须是一个非空序列
  • __getitem__方法会实现 [] 下标操作
  • __len__实际上直接返回 PyVarObject 里的 ob_size 属性
  • hypot
from math import hypot
# 返回 sqrt(x*x + y*y)
hypot(3,4) = 5
# 可以直接计算直角三角形斜边的长
  • __str____repr__的区别
    __str__是在 str() 函数中被使用,或者是在用 print 函数打印一个对象的时候才调用的,它返回的字符串对终端用户更友好;
    str() 和 repr() 都是 python 的内置函数,用来格式化字符串的函数,而 __str__`` __repr__是在类(对象)中对类(对象)本身进行字符串处理。
    如果定义了__repr__,但没有定义__str__,对象将表现为__str__=__repr__
    可以查看 stackoverflow 上的这个问题解答 stackoverflow,如果英文看不懂,可以看看翻译中文
  • ord()
    ord() 函数是 chr() 函数(对于8位的ASCII字符串)或 unichr() 函数(对于Unicode对象)的配对函数,它以一个字符(长度为1的字符串)作为参数,返回对应的 ASCII 数值,或者 Unicode 数值.
  • 变量泄露(python 2.7)
x = 'abc'
b = [x for x in 'bdef']
print x
# f
# 但是在 python 3 中不会出现这个问题
# 列表推导,生成器等推导式在 python 3 中有了自己的局部作用域,类似函数。
  • 元组功能
    元组是一种很强大的可以当作记录来用的数据类型,体现在元组拆包特性上。第二角色则是充当一个不可变的列表。
  • 列表生成列表
board = [ ['_'] * 3 for i in range(3)]
board
# [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
board[1][2] = 'X'
board
# [['_', '_', '_'], ['_', '_', 'X'], ['_', '_', '_'

上面的例子类似于:

board = []
for i in rage(3):
    row = ['_'] * 3
    board.append(row)

但是很容易写成这样:

board = [ ['_'] * 3] * 3
board 
# [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
board[1][2] = '0'
board
# [['_', '_', '0'], ['_', '_', '0'], ['_', '_', '0']]
# 类似于
row = ['_'] * 3
board = []
for i in rage(3):
    board.append(row)
# 在 board 中的 row 其实是同一对象的不同引用,改变其中任何一个就改变了所有
  • 一个关于 += 的谜题
t = (1, 2, [30, 40])
t[2] += [50, 60]

会发生什么呢?
a. t 变成 (1, 2, [30, 40, 50, 60])。
b. 因为 tuple 不支持对它的元素赋值,所以会抛出 TypeError 异常。
c. 以上两个都不是。
d. a 和 b 都是对
如果你看到这里,停止往下拉,思考一下,然后去解释器中运行一下。
很不幸,结果不像我像的那样,我一开始选择了 a,因为 t[2] 是一个列表,而列表是可变的,但是我忽略了 t 本身是一个元组的缘故,元组具有不可变的特性。其实它只完成了 t[2] + [50, 60] 的操作,在最后赋值的时候抛出异常了,所以答案是 d。可以得到 3 个教训:
   * 不要把可变对象放在元组里。
   * 增量赋值不是一个原子操作。
   * 可以查看 python 的字节码。(其实我没有看懂)

  • random.seed()
    seed() 方法改变随机数生成器的种子,可以在调用其他随机模块函数之前调用此函数。如果两次种子是相同的,那么生成的随机数是固定的。
  • 为什么切片和区间会忽略最后一个元素
    在切片和区间操作里不包含范围的最后一个元素是 Python 的风格,这个习惯符合 Python、C 和其他语言里以 0 作为起始下标的传统。
  • 当只有最后一个位置信息时,可以快速看出切片和区间里有几个元素:range(3) 和 my_list[:3] 都返回 3 个元素。
  • 当起始位置都可见时,可以快速计算切片和区间的长度,用后一个数减去第一个下标(stop - start)即可。
  • 可以利用任意一个下标来把序列分割成不重叠的两部分,只要写成 my_list[:x] 和 my_list[x:] 就可以了。
>>> l = [10, 20, 30, 40, 50, 60]
>>> l[:2] # 在下标2的地方分割
[10, 20]
>>> l[2:]
[30, 40, 50, 60]
>>> l[:3] # 在下标3的地方分割
[10, 20, 30]
>>> l[3:]
[40, 50, 60]

另外可以用 s[a:b:c] 的形式对 s 在 a 和 b 之间以 c 为间隔取值。a:b:c 这种用法只能作为索引或者下标用在 [] 中来返回一个切片对象:slice(a, b, c)
seq[start:stop:step] 进行求值的时候,Python 会调用 seq.__getitem__(slice(start, stop, step))

  • 代替列表
    虽然列表既灵活又简单,但面对各类需求时,我们可能会有更好的选择。比如,要存放 1000 万个浮点数的话,数组(array)的效率要高得多,因为数组在背后存的并不是 float 对象,而是数字的机器翻译,也就是字节表述。这一点就跟 C 语言中的数组一样。再比如说,如果需要频繁对序列做先进先出的操作,deque(双端队列)的速度应该会更块。
    • 数组
      若只包含数字的列表,那么 array.array 比 list 更高效。这个名为数组,跟 C 语言的数组一样精简。数组在 Python 3 中不支持 list.sort() 这种就地排序方法,需要用 sorted 函数。
    • 内存视图
      memoryview 是一个内置类,它能让用户在不复制内容的情况下操作同一个数组的不同切片。

    内存视图其实是泛化和去数学化的 NumPy 数组。它让你在不需要复制内容的前提下,在数据结构之间共享内存。其中数据结构可以是任何形式,比如 PIL图片、SQLite 数据库和 NumPy 的数组,等等。这个功能在处理大型数据集合的时候非常重要。-- Travis Oliphant ,NumPy 的主要作者。

    • Numpy 和 Scipy
      这两个库主要用于科学计算,而且需要自行安装这两个库。Numpy 底层是 C 语言写的,所以速度极快。
      Pandas 也利用了这个库,可以好好尝试一下。
      • 队列
        collections.deque 是一个线程安全,快速从两端添加或者删除元素的数据类型。注意双向队列只是优化了头尾的操作,从队列中间删除元素操作会慢一些。另外 queue 也实现了队列,它也是线程安全的。
  • Python 中的排序
    sorted 和 list.sort 背后的排序算法是 Timsort,它是一种自适应算法,会根据原始数据的顺序特点交替使用插入排序和归并排序,以达到最佳效率。这样的算法被证明是很有效的,因为来自真实世界的数据通常是有一定的顺序特点的。
  • 上下文管理器
    with 实现,依赖于 __enter____exit__ 函数。
class Test():
    def __enter__(self):
        print('enter')
        return self
    def __exit__(self, exc_type, exc_val, exc_tb):
        print('exit')
    def test(self):
        pass

with Test() as t:
    t.test()

可以基于类也可以基于 contextlib 模块

import contextlib
@contextlib.contextmanger
def file_open(name):
    # do enter thing
    yield {}
    # do exit thing
    • += extend
a = [1,2]
a += [3, 4]    --> √
a += (3, 4)    --> √
a = a + [3, 4]    --> √
a = a + (3, 4)    --> X
事实上 += 调用了 __iadd__ 方法,它里面调用了 extend 方法。这样
a.extend(range(3))     --> √
注意:append 会将原本的类型直接放入列表,extend 只会将元素放入列表
  • 元编程
    type 可以用来创建类
def test(self):
    return self.name
User = type('user', (基类相关,), {'name': 'ad', 'test': test})
obj = User()
obj.name     --->> ad
a = obj.test()
a          --->> ad
# 元类来控制类的实例化过程
# 在类的实例化过程中,首先会去寻找 metaclass,
# 找到了就按元类去创造类,找不到就使用 type 去创建类的实例
class MetaClass(type):
    def __new__(cls, *args, **kwargs):
        return super().__new__(cls, *args, **kwargs)

class Te(metaclass=MetaClass):
    def __init__(self, s):
        self.s = s
    
    def __str__(self):
        return self.s
  • _slots_
    我们知道动态语言允许我们直接在运行过程中给类加上需要的功能,但是有时候这个非常难受,我们想限制 class 的属性怎么办,比如只允许对实例添加有关属性。这个也作为优化内存访问的一个手段,尽管本意不是如此。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容