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

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

快速链接到答案:

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


当前回答

插入与追加

不是特稿,但可能会很有趣

假设您想要在列表中插入一些数据,然后反转它。最简单的方法是

count = 10 ** 5
nums = []
for x in range(count):
    nums.append(x)
nums.reverse()

然后你会想:把数字从最开始插入怎么样?所以:

count = 10 ** 5 
nums = [] 
for x in range(count):
    nums.insert(0, x)

但它却慢了100倍!如果我们设置count = 10 ** 6,它将慢1000倍;这是因为插入是O(n²),而追加是O(n)。

造成这种差异的原因是insert每次调用时都必须移动列表中的每个元素;Append只是在列表的末尾添加元素(有时它必须重新分配所有元素,但它仍然更快)

其他回答

特殊的方法

绝对的权力!

原始字符串中的反斜杠仍然可以转义引号。看到这个:

>>> print repr(r"aaa\"bbb")
'aaa\\"bbb'

注意,反斜杠和双引号都出现在最后的字符串中。

因此,你不能用反斜杠来结束一个原始字符串:

>>> print repr(r"C:\")
SyntaxError: EOL while scanning string literal
>>> print repr(r"C:\"")
'C:\\"'

这是因为实现原始字符串是为了帮助编写正则表达式,而不是为了编写Windows路径。在Gotcha - Windows文件名中的反斜杠上阅读关于这个的长讨论。

设置/ frozenset

可能一个容易被忽略的python内置程序是“set/frozenset”。

当你有一个像这样的列表[1,2,1,1,2,3,4]并且只想要像[1,2,3,4]这样的唯一性时很有用。

使用set()这就是你得到的结果:

>>> x = [1,2,1,1,2,3,4] 
>>> 
>>> set(x) 
set([1, 2, 3, 4]) 
>>>
>>> for i in set(x):
...     print i
...
1
2
3
4

当然,要得到列表中唯一的个数:

>>> len(set([1,2,1,1,2,3,4]))
4

你也可以使用set(). is子集()来判断一个列表是否是另一个列表的子集:

>>> set([1,2,3,4]).issubset([0,1,2,3,4,5])
True

从Python 2.7和3.0开始,你可以使用花括号来创建一个集合:

myset = {1,2,3,4}

以及集合理解:

{x for x in stuff}

详情如下: http://docs.python.org/library/stdtypes.html#set

可读正则表达式

在Python中,您可以将正则表达式拆分为多行,命名匹配并插入注释。

示例详细语法(来自Python):

>>> pattern = """
... ^                   # beginning of string
... M{0,4}              # thousands - 0 to 4 M's
... (CM|CD|D?C{0,3})    # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's),
...                     #            or 500-800 (D, followed by 0 to 3 C's)
... (XC|XL|L?X{0,3})    # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's),
...                     #        or 50-80 (L, followed by 0 to 3 X's)
... (IX|IV|V?I{0,3})    # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's),
...                     #        or 5-8 (V, followed by 0 to 3 I's)
... $                   # end of string
... """
>>> re.search(pattern, 'M', re.VERBOSE)

命名匹配示例(摘自正则表达式HOWTO)

>>> p = re.compile(r'(?P<word>\b\w+\b)')
>>> m = p.search( '(((( Lots of punctuation )))' )
>>> m.group('word')
'Lots'

由于字符串字面值的串联,你也可以在不使用re.VERBOSE的情况下详细地编写一个正则表达式。

>>> pattern = (
...     "^"                 # beginning of string
...     "M{0,4}"            # thousands - 0 to 4 M's
...     "(CM|CD|D?C{0,3})"  # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's),
...                         #            or 500-800 (D, followed by 0 to 3 C's)
...     "(XC|XL|L?X{0,3})"  # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's),
...                         #        or 50-80 (L, followed by 0 to 3 X's)
...     "(IX|IV|V?I{0,3})"  # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's),
...                         #        or 5-8 (V, followed by 0 to 3 I's)
...     "$"                 # end of string
... )
>>> print pattern
"^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$"

绝密属性

>>> class A(object): pass
>>> a = A()
>>> setattr(a, "can't touch this", 123)
>>> dir(a)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', "can't touch this"]
>>> a.can't touch this # duh
  File "<stdin>", line 1
    a.can't touch this
                     ^
SyntaxError: EOL while scanning string literal
>>> getattr(a, "can't touch this")
123
>>> setattr(a, "__class__.__name__", ":O")
>>> a.__class__.__name__
'A'
>>> getattr(a, "__class__.__name__")
':O'