Python 的隐藏功能

答案

链接比较运算符:

>>> x = 5
>>> 1 < x < 10
True
>>> 10 < x < 20 
False
>>> x < 10 < x*10 < 100
True
>>> 10 > x <= 9
True
>>> 5 == x > 4
True

如果您认为它正在做1 < x ,它表示为True ,然后比较True < 10 ,它也是True ,那么不,那真的不发生什么(请参阅最后一个示例。)它实际上是转化为1 < x and x < 10以及x < 10 and 10 < x * 10 and x*10 < 100 ,但键入次数较少,每个术语仅计算一次。

获取 python regex 解析树以调试您的 regex。

正则表达式是 python 的一个很棒的功能,但是调试它们可能会很麻烦,而且很容易弄错正则表达式。

幸运的是,python 可以通过传递未记录的,实验性的,隐藏的标志re.DEBUG (实际上是 128 个)传递给re.compile来打印正则表达式分析树。

>>> re.compile("^\[font(?:=(?P<size>[-+][0-9]{1,2}))?\](.*?)[/font]",
    re.DEBUG)
at at_beginning
literal 91
literal 102
literal 111
literal 110
literal 116
max_repeat 0 1
  subpattern None
    literal 61
    subpattern 1
      in
        literal 45
        literal 43
      max_repeat 1 2
        in
          range (48, 57)
literal 93
subpattern 2
  min_repeat 0 65535
    any None
in
  literal 47
  literal 102
  literal 111
  literal 110
  literal 116

一旦了解了语法,就可以发现错误。在那里,我们可以看到,我忘了逃脱[][/font]

当然,您可以将其与所需的任何标志(例如带注释的正则表达式)结合使用:

>>> re.compile("""
 ^              # start of a line
 \[font         # the font tag
 (?:=(?P<size>  # optional [font=+size]
 [-+][0-9]{1,2} # size specification
 ))?
 \]             # end of tag
 (.*?)          # text between the tags
 \[/font\]      # end of the tag
 """, re.DEBUG|re.VERBOSE|re.DOTALL)

枚举

用 enumerate 包装一个可迭代对象,它将产生该项目及其索引。

例如:

>>> a = ['a', 'b', 'c', 'd', 'e']
>>> for index, item in enumerate(a): print index, item
...
0 a
1 b
2 c
3 d
4 e
>>>

参考文献:

创建生成器对象

如果你写

x=(n for n in foo if bar(n))

您可以找出生成器并将其分配给 x。现在,这意味着您可以

for n in x:

这样做的好处是您不需要中间存储,如果需要的话

x = [n for n in foo if bar(n)]

在某些情况下,这可能会导致速度显着提高。

您可以在生成器的末尾附加许多 if 语句,基本上是复制嵌套的 for 循环:

>>> n = ((a,b) for a in range(0,2) for b in range(4,6))
>>> for i in n:
...   print i 

(0, 4)
(0, 5)
(1, 4)
(1, 5)

iter()可以接受可调用参数

例如:

def seek_next_line(f):
    for c in iter(lambda: f.read(1),'\n'):
        pass

iter(callable, until_value)函数重复调用callable并产生其结果,直到返回until_value为止。

注意可变的默认参数

>>> def foo(x=[]):
...     x.append(1)
...     print x
... 
>>> foo()
[1]
>>> foo()
[1, 1]
>>> foo()
[1, 1, 1]

相反,您应该使用表示 “未给定” 的前哨值,并默认替换为您想要的可变变量:

>>> def foo(x=None):
...     if x is None:
...         x = []
...     x.append(1)
...     print x
>>> foo()
[1]
>>> foo()
[1]

将值发送到生成器函数中 。例如,具有以下功能:

def mygen():
    """Yield 5 until something else is passed back via send()"""
    a = 5
    while True:
        f = (yield a) #yield a and possibly get f in return
        if f is not None: 
            a = f  #store the new value

您可以:

>>> g = mygen()
>>> g.next()
5
>>> g.next()
5
>>> g.send(7)  #we send this back to the generator
7
>>> g.next() #now it will yield 7 until we send something else
7

如果您不喜欢使用空格来表示作用域,则可以通过发出以下命令来使用 C 样式的 {}:

from __future__ import braces

切片运算符中的 step 参数。例如:

a = [1,2,3,4,5]
>>> a[::2]  # iterate over the whole list in 2-increments
[1,3,5]

x[::-1]的特殊情况是 “x 反转” 的有用用法。

>>> a[::-1]
[5,4,3,2,1]

装饰工

装饰器允许将一个函数或方法包装在另一个函数中,该函数或方法可以添加功能,修改参数或结果等。您可以在函数定义上方一行以 “at” 符号(@)开头编写装饰器。

示例显示了一个print_args装饰器,该装饰器在调用装饰函数之前将其打印出来:

>>> def print_args(function):
>>>     def wrapper(*args, **kwargs):
>>>         print 'Arguments:', args, kwargs
>>>         return function(*args, **kwargs)
>>>     return wrapper

>>> @print_args
>>> def write(text):
>>>     print text

>>> write('foo')
Arguments: ('foo',) {}
foo