小心Python的“坑”(持续更新)

来源:互联网 发布:洛阳驱逐舰数据 编辑:程序博客网 时间:2024/06/06 06:42

用了Python也有三个多月了,在为这个语言如此简单易用而赞叹的同时,也碰到了不少“坑”的地方,开个博文总结下:


1. list添加一个元素很容易,像下面这样:

l = []l.append('hello')

dict怎么添加?没有insert,也没有append,怎么办?

>>> d = {}>>> d['key'] = 'value'>>> d{'key': 'value'}>>> d[3] = 4>>> d{3: 4, 'key': 'value'}

看出来了吗?直接写一个K-V组合,就自动添加进来了

别告诉我你不知道怎么删除,del


2.  先看这个

>>> t = ()>>> type(t)<type 'tuple'>>>> t = (1)>>> type(t)<type 'int'>>>> t = (1, 2)>>> type(t)<type 'tuple'>

有没有觉得哪里不对劲?为什么中间那个是int类型,不是tuple了?我承认我当时没看清楚文档,所以碰到了这个问题:

import threadingdef print_arg(arg):    print argstr = 'test-string'thr = threading.Thread(target=print_arg, args=(str))thr.start()thr.join()print 'threading done'

例子很简单,创建一个线程,线程的任务就是打印传入的参数,由于传入的参数要求是tuple,所以我当时想当然的用括号包裹了一下,然后运行。

Exception in thread Thread-1:Traceback (most recent call last):  File "/usr/lib/python2.7/threading.py", line 551, in __bootstrap_inner    self.run()  File "/usr/lib/python2.7/threading.py", line 504, in run    self.__target(*self.__args, **self.__kwargs)TypeError: print_arg() takes exactly 1 argument (11 given)threading done

咦?为什么我明明只传入一个参数,却提示我传入了11个?

仔细翻看原文档,才注意到,构建tuple是靠逗号,而不是圆括号,我搜索了Python为什么1个元素的tuple不也这么写,他们解释是括号是用来组合的,比如计算的时候,括号的优先级最高(源链接找不到了)。

那我怎么构建一个元素的tuple?很简单,只是不优雅

>>> t = (1,)>>> type(t)<type 'tuple'>>>> t = 1,>>> type(t)<type 'tuple'>

tuple的关键是那个逗号,而不是括号,由于tuple的输出格式都是用圆括号括起来,所以时间久了,就自然而然认为圆括号是tuple的核心。

所以上面那个例子,只要在括号里面的str后面,加上一个逗号,就可以得到需要的结果了。

More:11个参数是怎么回事?因为在Python里面,string和tuple有个共同特性,都是iterable的,所以传入的str被拆解成11个字符的tuple,这也是为什么提示传入了11个参数


3. decorator使用注意

写一个decorator的时候,最好在实现之前加上functools的wrap,它能保留原有函数的名称和docstring,例如:

from functools import wrapsdef my_decorator(f):    @wraps(f)    # 最好加上这一句    def wrapper(*args, **kwds):        print 'Calling decorated function'        return f(*args, **kwds)    return wrapper@my_decoratordef example():    """Docstring"""    print 'Called example function'print example.__name__, example.__doc__

程序运行之后的输出是

example Docstring
如果去掉了 @wraps(f) 这一行,得到的结果会是这样的

wrapper None


4. lambda表达式中使用注意:

>>> x = 10>>> a = lambda y: x+y>>> x = 20>>> b = lambda y: x+y>>> a(10)30>>> b(10)30

在这里a(10)和b(10)输出结果相同的原因是:x 在lambda表达式中是一个自由变量,在运行时确定,而不是定义的时候(the value of x used in the lambda expression is a free variable that gets bound at runtime, not definition time),如果需要保存 x 的值,需要这么使用:

>>> x = 10>>> a = lambda y, x=x: x+y>>> x = 20>>> b = lambda y, x=x: x+y>>> a(10)20>>> b(10)30

0 0
原创粉丝点击