07-01結構與封裝

解構與封裝

解構

什麼是結構?如下講兩個例子
解構:按照元素順序, 把線性結構的元素賦值給變量。

簡單一點的例子

In [26]: x = 1

In [27]: y = 2

In [28]: tmp = x

In [29]: x = y 

In [30]: y = tmp

In [31]: print(x, y)
2 1

複雜一點的例子

In [32]: x, y = y, x

In [33]: print(x, y)
1 2

In [36]: lst = [1, 2]

In [37]: first = lst[0]

In [38]: second = lst[1]

In [39]: first, second = lst    # 解構

In [40]: print(first, second)
1 2

封裝

  • 定義一個元組, 可以省略小括號
  • 封裝出來的一定是元組
In [43]: t = 1, 2

In [44]: t
Out[44]: (1, 2)

In [45]: type(t)
Out[45]: tuple

定義一個元組, 可以省略小括號

In [46]: t1 = (1, 2)

In [47]: t2 = 1, 2

t1和t2的效果是相等的。

封裝出來的一定是元組

python3與python2解構不同之處

上述就是Python2和Python3解構的相同之處,Python3還帶來一些新的解構變化

總結:

  • 不加*號的解構
    1. 元素按照順序賦值給變量。
    2. 變量和元素必須匹配。
  • 加*號的解構
    1. 加星號變量, 可以接收任意個數的元素。
    2. 加星號的變量不能單獨出現。在一個表達式也只能出現1次
    3. *號位置可以在表達式中任意地方出現。(左中右)

加*號的場景

依然用實例說話

場景1:*號參數位於中間

In [48]: lst = list(range(1000))

In [49]: head, *mid, tail = lst

In [50]: head
Out[50]: 0

In [51]: tail
Out[51]: 999

In [52]: mid
Out[52]: 
[1,
 2,
 ...
 ...
 998]

In [67]: first, sceond, *other, last = lst  # 這種情況也是允許的

In [68]: first
Out[68]: 0

In [69]: sceond
Out[69]: 1

In [70]: other
Out[70]: [2, 3]

In [71]: last
Out[71]: 4

場景2:*號位於最右邊

In [53]: lst = list(range(5))

In [54]: head, *tail = lst

In [55]: head
Out[55]: 0

In [56]: tail
Out[56]: [1, 2, 3, 4]

In [63]: first, sceond, *other = lst   # 這種情況下是允許的

In [64]: first
Out[64]: 0

In [65]: sceond
Out[65]: 1

In [66]: other
Out[66]: [2, 3, 4]

場景3:只有一個星號, 沒有其他參數

In [58]: *lst2 = lst    # 左邊只有一個加星號的變量是不行的
  File "<ipython-input-58-98211a44ccfb>", line 1
    *lst2 = lst
               ^
SyntaxError: starred assignment target must be in a list or tuple

場景4:星號位於最左邊

In [59]: *head, tail = lst   # 這種是OK的

In [60]: head
Out[60]: [0, 1, 2, 3]

In [61]: tail
Out[61]: 4

場景5:多個星號

In [62]: head, *m1, *m2, tail = lst    # 兩個*號是不行的
  File "<ipython-input-62-1fc1a52caa8e>", line 1
    head, *m1, *m2, tail = lst
                              ^
SyntaxError: two starred expressions in assignment

左右有多個加星號的變量也是不行的。

不加*號場景

場景1:左邊變量數超過右邊元素個數的時候

In [72]: v1, v2, v3, v4, v5, v6, v7 = lst   # 左邊變量數超過右邊元素個數的時候, 是不行。
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-72-9366cfb498a1> in <module>()
----> 1 v1, v2, v3, v4, v5, v6, v7 = lst

ValueError: not enough values to unpack (expected 7, got 5)

場景2:左邊變量數小於右邊元素個數

In [73]: v1, v2 = lst   # 左邊變量數小於右邊元素個數, 且左邊沒有加星號的變量
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-73-d7b0a4e7871e> in <module>()
----> 1 v1, v2 = lst

ValueError: too many values to unpack (expected 2)

解構返回的都是列表

In [83]: f, *t = (1, 2, 3, 4)

In [84]: t        # 返回的都是一個列表
Out[84]: [2, 3, 4]

_下劃線在解構中的作用

python的一個慣例, 使用單個下劃線_表示丟棄該變量。

In [85]: head, *_, tial = lst

In [86]: head
Out[86]: 0

In [87]: tail 
Out[87]: 4

In [88]: _   # python的一個慣例, 使用單個下劃線_表示丟棄該變量。
Out[88]: 4

單個下劃線也是python合法的標識符, 但是如果不是要丟棄一個變量, 通常不要用單個下劃線表示一個有意義的變量。
在gettext, 多語言gettext('bbbb'), 通常會重命名_ _('dfasfdasd')
在gettext中的慣例, 會覆蓋python中_丟棄的變量。

In [2]: head, *_ = 'I love Python'

In [3]: head
Out[3]: 'I'

In [4]: _
Out[4]: 'I'

ipython把返回值臨時保存在_

In [5]: [1, 2, 3, 4]
Out[5]: [1, 2, 3, 4]

In [6]: _
Out[6]: [1, 2, 3, 4]

多層次的解構

解構也可以用在多層次(比如一個列表中還有一個元組)的語句上。
非常複雜的數據結構, 多層嵌套的線性結構的時候, 可以用結構快速提取其中的值。
解構用的多的地方在於函數的返回值, 函數返回值封裝一個元組

In [11]: lst = [1, (2, 3), 5]

In [12]: _, v, *_ = lst

In [13]: _, val = v   # 複雜的實現

In [15]: val
Out[15]: 3

In [16]: _, (_, val), *_ = lst   # 直接的實現

In [17]: val
Out[17]: 3

解構是支持多層次的

In [25]: lst
Out[25]: [0, (1, 2), 2, 3, 4, 5, 6, 7, 8, 9]

In [26]: _, (*_, tail), *_ = lst

In [27]: tail
Out[27]: 2

In [28]: _, [*_, tail], *_ = lst   # 可以以列表的形式

In [29]: tail
Out[29]: 2

非常複雜的數據結構, 多層嵌套的線性結構的時候, 可以用結構快速提取其中的值。

解構用的多的地方在於函數的返回值, 函數返回值封裝一個元組

In [33]: key, _, value = 'env = prod'.partition('=')  # 快速匹配key, value

In [34]: key
Out[34]: 'env '

In [35]: value
Out[35]: ' prod'

沒有解構, 我們也可以活下來, 但是有了結構, 生活很美好
解構這個特性, 被很多的語言借鑑。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章