zoukankan      html  css  js  c++  java
  • 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'
    
    没有解构, 我们也可以活下来, 但是有了结构, 生活很美好
    解构这个特性, 被很多的语言借鉴。
    
  • 相关阅读:
    Hello_Area_Description 任务三:Project Tango采集区域描述数据
    智能小车 机器人
    Hello_Depth_Perception 任务二:Project Tango采集深度感知数据
    Project Tango Explorer
    make运行阶段划分
    关于chroot
    xargs命令
    debian配置集锦
    gdb使用技巧
    gdb调试使用autotools工程的项目
  • 原文地址:https://www.cnblogs.com/cishi/p/13023170.html
Copyright © 2011-2022 走看看