关于Python的一些笔记


有的是坑,也有的是进阶内容或容易忘记的知识点。

注:本文不定时更新

1. 参数魔法

def try_to_change_1(n):
    n = "another"
    
name = "other"
try_to_change(name)
print name #output:other  name不会改变

def try_to_change_2(n):
    n[0] = "another"
    
names = ["name1", "name2", "name3"]
try_to_change_2(names)
print name #这次可以改变name的值

为什么try_to_change_1不会改变name的值?实际两个函数做的事情如下:

#1
name = "other"
n = name
n = "another"

#2
name = [x, x, x]
n = name
n[0] = "another"

如果你知道Python里的对象引用,自然就会明白。如果想要避免try_to_change_2的情况,可以复制一个列表的副本:

names = ["name1", "name2", "name3"]
n = names[:]

2. 函数参数的默认值在函数初始化的时候定义

def func(a=[]):
    a.append('test')
    print a
    
for i in range(3):
    func()
    
#output:
#['test']
#['test', 'test']
#['test', 'test', 'test']

解决办法:

def func(a=None):
    if a is None:
        a = []
    # do something

3. functool.wraps()的作用

我第一次知道functools.wraps()是在flask的login_required。

有时我们需要知道函数的一些信息,例如函数参数、注释等,但是经过装饰器,看到的就是装饰器的信息,而wraps()的作用就是转移函数的这些信息。

4. 怎么做一个缓存

可以使用装饰器。

def memoize(func):
    cache = {}
    @functools.wraps(func)
    def wrapper(*args):
        if args in cache:
            return cache(args)
        result = func(*args)
        cache[args] = result
        return result
    return wrapper

5. 包含列表或者元组的list的排序

l = [[2, 3], [6, 7], [3, 34], [24, 64], [1, 43]]

l.sort(key=lambda list: list[0])
sorted(l, key=lambda list: list[0])