Python编程语言中有哪些鲜为人知但很有用的特性?

尽量将答案限制在Python核心。 每个回答一个特征。 给出一个例子和功能的简短描述,而不仅仅是文档链接。 使用标题作为第一行标记该特性。

快速链接到答案:

参数解包 牙套 链接比较运算符 修饰符 可变默认参数的陷阱/危险 描述符 字典默认的.get值 所以测试 省略切片语法 枚举 其他/ 函数作为iter()参数 生成器表达式 导入该 就地值交换 步进列表 __missing__物品 多行正则表达式 命名字符串格式化 嵌套的列表/生成器推导 运行时的新类型 .pth文件 ROT13编码 正则表达式调试 发送到发电机 交互式解释器中的制表符补全 三元表达式 试着/ / else除外 拆包+打印()函数 与声明


当前回答

python的一个小错误。通常快速连接字符串列表的方法是,

''.join(list_of_strings)

其他回答

Python的高级切片操作有一个鲜为人知的语法元素,即省略号:

>>> class C(object):
...  def __getitem__(self, item):
...   return item
... 
>>> C()[1:2, ..., 3]
(slice(1, 2, None), Ellipsis, 3)

不幸的是,它几乎没有什么用处,因为只有在涉及元组时才支持省略号。

使用关键字参数作为赋值

有时需要根据一个或多个参数构建一系列函数。然而,这很容易导致闭包都引用相同的对象和值:

funcs = [] 
for k in range(10):
     funcs.append( lambda: k)

>>> funcs[0]()
9
>>> funcs[7]()
9

可以通过将lambda表达式转换为仅依赖其参数的函数来避免这种行为。关键字参数存储绑定到它的当前值。函数调用不需要改变:

funcs = [] 
for k in range(10):
     funcs.append( lambda k = k: k)

>>> funcs[0]()
0
>>> funcs[7]()
7

元组在for循环、列表推导式和生成器表达式中的解包:

>>> l=[(1,2),(3,4)]
>>> [a+b for a,b in l ] 
[3,7]

在这个习语中,用于迭代字典中的(键,数据)对:

d = { 'x':'y', 'f':'e'}
for name, value in d.items():  # one can also use iteritems()
   print "name:%s, value:%s" % (name,value)

打印:

name:x, value:y
name:f, value:e

reversed()内置。在很多情况下,它使得迭代更加简洁。

简单的例子:

for i in reversed([1, 2, 3]):
    print(i)

生产:

3
2
1

然而,reversed()也适用于任意迭代器,例如文件中的行或生成器表达式。

__getattr__ ()

getattr是一种创建泛型类的好方法,在编写API时尤其有用。例如,在FogBugz Python API中,getattr用于无缝地将方法调用传递给web服务:

class FogBugz:
    ...

    def __getattr__(self, name):
        # Let's leave the private stuff to Python
        if name.startswith("__"):
            raise AttributeError("No such attribute '%s'" % name)

        if not self.__handlerCache.has_key(name):
            def handler(**kwargs):
                return self.__makerequest(name, **kwargs)
            self.__handlerCache[name] = handler
        return self.__handlerCache[name]
    ...

当有人调用FogBugz.search(q='bug')时,他们实际上不会调用搜索方法。相反,getattr通过创建一个新函数来处理调用,该函数包装了makerequest方法,该方法将适当的HTTP请求发送给web API。任何错误都将由web服务分派并传递回用户。