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中也有隱藏彩蛋,你知道嗎?


    分享到:


    相關文章: