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'

没有解构, 我们也可以活下来, 但是有了结构, 生活很美好
解构这个特性, 被很多的语言借鉴。
原文地址:https://www.cnblogs.com/cishi/p/13023170.html