python中也有隐藏彩蛋,你知道吗?

python中也有隐藏彩蛋,你知道吗?

可否带我飞?

<code>

import

antigravity/<code>
  • antigravity 模块是 Python 开发人员发布的少数复活节彩蛋之一.
  • import antigravity 会打开一个 Python 的经典 XKCD 漫画页面.
  • 不止如此. 这个复活节彩蛋里还有一个复活节彩蛋. 如果你看一下代码, 就会发现还有一个函数实现了 XKCD's geohashing 算法.
  • python中也有隐藏彩蛋,你知道吗?

    自动打开的xkcd漫画页面

    连Python也知道爱是难言的

    <code>

    import

    this

    /<code>

    执行这句会发生什么?

    <code>

    The

    Zen of Python, by Tim Peters

    Beautiful

    is better than ugly.

    Explicit

    is better than implicit.

    Simple

    is better than complex.

    Complex

    is better than complicated.

    Flat

    is better than nested.

    Sparse

    is better than dense.

    Readability

    counts.

    Special

    cases ,aren't special enough to break the rules.

    Although

    practicality beats purity.

    Errors

    should never pass silently.

    Unless

    explicitly silenced.

    In

    the face of ambiguity, refuse the temptation to guess.

    There

    should be one-- and preferably only one --obvious way to do it.

    Although

    that way may not be obvious at first unless you're Dutch.

    Now

    is better than never.

    Although

    never is often better than *right* now.

    If

    the implementation is hard to explain, it's a bad idea.

    If

    the implementation is easy to explain, it may be a good idea.

    Namespaces

    are one honking great idea -- let's do more of those!

    Process

    finished with exit code 0

    /<code>

    这又是一个复活节彩蛋,实际它的源码就一个py文件,打印了这些信息,然后什么都没干

    else无处不在

    在Python里else已经不局限在if判断里了,它出现在众多逻辑处理中

    • for......else......
    <code>

    def

    does_exists_num

    (l, to_find)

    :

    for

    num

    in

    l:

    if

    num == to_find: print(

    "Exists!"

    )

    break

    else

    : print(

    "Does not exist"

    ) some_list = [

    1

    ,

    2

    ,

    3

    ,

    4

    ,

    5

    ] does_exists_num(some_list,

    4

    ) does_exists_num(some_list,

    -1

    ) /<code>

    当for循环中执行了break,就不会执行else下的语句,要注意continue不会受此影响

    <code>

    try

    :

    pass

    except

    : print(

    "Exception occurred!!!"

    )

    else

    : print(

    "Try block executed successfully..."

    ) /<code>

    同样的不出现异常的时候,执行else语句

    私有不私有?

    <code>

    class

    Yo

    (object)

    :

    def

    __init__

    (self)

    :

    self.__honey =

    True

    self.bitch =

    True

    Yo().bitch Yo().__honey Yo()._Yo__honey /<code>

    双下划线私有变量如何完成私有变量特性的?实际是python解释器默认把双下划线开头的变量重命名了,命名方式为:_类名__varname

    更快的 +=

    <code>

    import

    timeit

    print

    (timeit.timeit(

    "s1 = s1 + s2 + s3"

    , setup=

    "s1 = ' ' * 100000; s2 = ' ' * 100000; s3 = ' ' * 100000"

    , number=

    100

    ))

    print

    (timeit.timeit(

    "s1 += s2 + s3"

    , setup=

    "s1 = ' ' * 100000; s2 = ' ' * 100000; s3 = ' ' * 100000"

    , number=

    100

    )) /<code>

    连接两个以上的字符串时 += 比 + 更快, 因为在计算过程中第一个字符串 (例如, s1 += s2 + s3 中的 s1) 不会被销毁,就是 += 执行的是追加操作,少了一个销毁新建的动作。

    来做个巨大的字符串吧!

    <code>

    def

    add_string_with_plus

    (iters)

    :

    s =

    ""

    for

    i

    in

    range(iters): s +=

    "xyz"

    assert

    len(s) ==

    3

    *iters

    def

    add_bytes_with_plus

    (iters)

    :

    s =

    b""

    for

    i

    in

    range(iters): s +=

    b"xyz"

    assert

    len(s) ==

    3

    *iters

    def

    add_string_with_format

    (iters)

    :

    fs =

    "{}"

    *iters s = fs.format(*([

    "xyz"

    ]*iters))

    assert

    len(s) ==

    3

    *iters

    def

    add_string_with_join

    (iters)

    :

    l = []

    for

    i

    in

    range(iters): l.append(

    "xyz"

    ) s =

    ""

    .join(l)

    assert

    len(s) ==

    3

    *iters

    def

    convert_list_to_string

    (l, iters)

    :

    s =

    ""

    .join(l)

    assert

    len(s) ==

    3

    *iters print(timeit(add_string_with_plus(

    10000

    ))) print(timeit(add_bytes_with_plus(

    10000

    ))) print(timeit(add_string_with_format(

    10000

    ))) print(timeit(add_string_with_join(

    10000

    ))) l = [

    "xyz"

    ] *

    10000

    print(timeit(convert_list_to_string(l,

    10000

    ))) print(timeit(add_string_with_plus(

    100000

    ))) print(timeit(add_bytes_with_plus(

    100000

    ))) print(timeit(add_string_with_format(

    100000

    ))) print(timeit(add_string_with_join(

    100000

    ))) l = [

    "xyz"

    ]*

    100000

    print(timeit(convert_list_to_string(l,

    100000

    ))) /<code>
  • 不要用 + 去生成过长的字符串, 在 Python 中, str 是不可变得, 所以在每次连接中你都要把左右两个字符串复制到新的字符串中. 如果你连接四个长度为10的字符串, 你需要拷贝 (10+10) + ((10+10)+10) + (((10+10)+10)+10) = 90 个字符而不是 40 个字符. 随着字符串的数量和大小的增加, 情况会变得越发的糟糕 (就像add_bytes_with_plus 函数的执行时间一样)
  • 更建议使用 .format. 或 % 语法 ,但是对于短字符串, 它们比 + 稍慢一点.
  • 如果你所需的内容已经以可迭代对象的形式提供了, 使用 ''.join(可迭代对象) 要快多了.
  • add_string_with_plus 的执行时间没有像 add_bytes_with_plus 一样出现二次增加是因为解释器会如同上一个列子所讨论的一样优化 +=. 用 s = s + "x" + "y" + "z" 替代 s += "xyz" 的话, 执行时间就会二次增加了.
  • <code>

    def

    add_string_with_plus

    (iters)

    :

    s =

    ""

    for

    i

    in

    range(iters): s = s +

    "x"

    +

    "y"

    +

    "z"

    assert

    len(s) ==

    3

    *iters print(timeit(add_string_with_plus(

    10000

    ))) print(timeit(add_string_with_plus(

    100000

    ))) /<code>

    [] = ()

    看着奇怪但能正确运行的语句,语句在语义上是正确的 (解包一个空的 tuple 并赋值给 list)'a'[0][0][0][0][0] 在语义上也是正确的, 因为在 Python 中字符串同时也是序列(可迭代对象支持使用整数索引访问元素).

    ++和--运算符

    <code>a = 5
    

    print

    (a)

    print

    (++a)

    print

    (--a) /<code>

    注意python 里没有 ++ 操作符. 这其实是两个 + 操作符.++a 被解析为 +(+a) 最后等于 a. --a 同理.

    本地变量数量

    Python 使用 2个字节存储函数中的本地变量.

    理论上, 这意味着函数中只能定义65536个变量. 但是,Python 内置了一个方便的解决方案,可用于存储超过2^16个变量名. 下面的代码演示了当定义了超过65536个局部变量时堆栈中发生的情况

    <code>

    import

    dis exec(

    """ def f(): """

    +

    """ """

    .join([

    "X"

    +str(x)+

    "="

    + str(x)

    for

    x

    in

    range(

    65539

    )])) f() print(dis.dis(f))/<code>

    'abc'.count('') == 4

    <code>

    print

    (

    'abc'

    .count(

    ''

    ) == 4) /<code>

    下面这个方法能更好的说明问题

    <code>def count(s, 

    sub

    ): result =

    0

    for

    i

    in

    range(

    len

    (s) +

    1

    -

    len

    (

    sub

    )): result += (s[i:i +

    len

    (

    sub

    )] ==

    sub

    )

    return

    result/<code>

    这个行为是由于空子串('')与原始字符串中长度为0的切片相匹配导致的.

    python中也有隐藏彩蛋,你知道吗?


    分享到:


    相關文章: