列表浅拷贝与深拷贝

- 引入场景

    list1 = ['JimGreen', 'LiLei', [1, 2, 3]]
    list2 = list1
    list1[0] = 'KateGreen'
    print(list2) # ['KateGreen', 'LiLei', [1, 2, 3]]

- 现在,想这样,修改list1的值时候,list2不受影响,该怎么办,答案就是使用'浅拷贝'
  list.copy()

    list1 = ['JimGreen', 'LiLei', [1, 2, 3]]
    list2 = list1.copy() # ['JimGreen', 'LiLei', [1, 2, 3]]
    list1[0] = 'KateGreen'
    print(list1) # ['KateGreen', 'LiLei', [1, 2, 3]]
    print(list2) # ['JimGreen', 'LiLei', [1, 2, 3]]

    - 可以看出,修改list1的值,确实不会影响list2的值,他们相互隔离开了
      但是,实际的结果真是这样吗?

    list1 = ['JimGreen', 'LiLei', [1, 2, 3]]
    list2 = list1.copy()
    list1[2][0] = 111
    print(list2) # ['JimGreen', 'LiLei', [111, 2, 3]] 值依旧被修改

    - 结论就是,浅拷贝这种方式,当元素是'不可变对象'的时候,两个列表对象确实是相互隔离开的,互不影响
      但是,若修改'可变对象元素',值依旧会互相影响

- 终极的隔离: 深拷贝

    list1 = ['JimGreen', 'LiLei', [1, 2, 3]]
    list2 = copy.deepcopy(list1)
    list1[2][0] = 111
    print(list2) # ['JimGreen', 'LiLei', [1, 2, 3]] 值不受影响

- 结论

    - 实现普通的隔离,使用'浅拷贝'

    - 实现终极隔离,使用'深拷贝'

异常

- 万能写法

    - 基础版示例:定义自己的错误

    try:
        enter = int(input('Please enter a number: '))
        result = 10 / enter
        print(result)
    except:
        print('捕获错误')

    - 改进版:捕获python解释器抛出的错误

    try:
        enter = int(input('Please enter a number: '))
        result = 10 / enter
        print(result)
    except Exception as e:
        print('捕获错误为: {}'.format(e))

- 捕获python解释器抛出的错误:最后一行报错的第一个单词

    number = int('king')
    print(number)

    # 异常单词
    ValueError: invalid literal for int() with base 10: 'king'


- 完整语法

    try:
        ...... # 尝试执行的代码

    except xxxError:
        ......# 捕获异常要执行的代码
    except xxxError:
        ......# 捕获异常要执行的代码
    except xxxError:
        ......# 捕获异常要执行的代码

    else:
        ......# 没有触发异常,会执行的代码

    finally:
        .......# 无论是否异常,都会执行的代码


- 实例

    try:
        enter = int(input('Please enter a number: '))
        result = 10 / enter
        print(result)
    except ValueError:
        print('请填入整数')
    except ZeroDivisionError:
        print('被除数不能为0')

    else:
        print('恭喜,程序没有触发错误!')

    finally:
        print('程序到此结束')
- 异常的传递性:当函数/方法触发异常时,会将异常传递给'调用方'
  因此,我们把捕获异常的代码放在'调用方'(通常指'主程序/主函数'),从而不必在 函数/方法中
  编写捕获异常的代码,从而简化代码量

    def demo1():
        return int(input('Please enter a number: ')) # 输入'w'


    def demo2():
        print(demo1())

    print(demo2())

    '''
      - 由于异常的传递性,所以报了三处错误

      - 实际开发中,看异常的时候,我们看最后一行错误即可,因为那是错误的'源头'

      Traceback (most recent call last):
      File "D:/Test_Demo/test_demoes/tools/test_class.py", line 8, in <module>
        print(demo2())
      File "D:/Test_Demo/test_demoes/tools/test_class.py", line 6, in demo2
        print(demo1())
      File "D:/Test_Demo/test_demoes/tools/test_class.py", line 2, in demo1
        return int(input('Please enter a number: '))
    ValueError: invalid literal for int() with base 10: 'q'

    '''

    - 改进示例

    def demo1():
        return int(input('Please enter a number: '))


    def demo2():
        print(demo1())

    try: # 捕获异常的逻辑,放在主程序,从而简化了被调用方的代码量
        print(demo2())
    except ValueError:
        print('请输入一个整数')
    except Exception:
        print('未知错误')
- 主动抛出异常(except...相当于触发系统内置的异常): raise + Exception
  raise属于自定义异常,比如业务需求,密码长度小于6,就抛出'密码长度错误'异常


- 实例

def input_pwd():
    msg = input('请输入密码: ')
    if len(msg) >=8: # 密码长度大于/等于8,就返回密码,不是则主动触发异常
        return msg
    raise Exception('密码长度小于8位')

try: # 把 try 的语句放在主程序
    print(input_pwd())
except Exception as e:
    print('捕获的错误为: {}'.format(e))

global:在函数内部,用来修改全局变量(不可变类型)的值

- 引入场景:两个变量x之间,互相独立,互不干扰

    x = 123

    def test():
        x = 456

    test()
    print(x) # 123

- 此时,如果想在函数内部,改变全局变量'x'的值怎木破,使用'global'

    x = 123

    def test():
        global x # 声明global
        x = 456

    test()
    print(x) # 456

- 如果变量存储的是'可变类型',就不用这么麻烦了,直接使用即可

    x = [1,2,3]

    def test():
        x.append(4)

    test()
    print(x) # [1,2,3,4]

nonlocal:在函数内部,用来改变最外层函数的变量值(不可变类型)

- 引入场景:外层 x 的值是不会变的

    def wrapper():
        x = 123
        def inner():
            x = 456
        inner()
        print('wrapper里面的x值为: ',x) # 123

    wrapper()

- 引入 nonlocal,修改外层函数的变量值

    def wrapper():
        x = 123
        def inner():
            nonlocal x # 声明nonlocal
            x = 456
        inner()
        print('wrapper里面的x值为: ',x) # 456

    wrapper()

- 如果变量存储的是'可变类型',就不用这么麻烦了,直接使用即可


    def wrapper():
        x = [1,2,3,4]
        def inner():
            x.append(5)
        inner()
        print('wrapper里面的x值为: ',x) # [1, 2, 3, 4, 5]

    wrapper()

global 和 nonlocal 小结

- 可以把 nonlocal 当成 'global'的小变种(函数范围指向最外层函数)

- global 就是变更全局变量的值

yield的用法

- 相当于return,返回值,区域在于 使用return语句,余下的代码就不再执行,yield返回以后,程序会被挂起,再次释放会执行余下的代码

- 接收 '生成器.send("xxx")'传过来的值

- 实例1:挂起

    def action(name):
        print('准备开始...')
        while True:
            yield 
            print('{}: yield挂起后继续执行...'.format(name))

    res = action('Jim Green') 
    print(res) # <generator object action at 0x000001CE70832F10> 第一次执行的时候,先初始化,不执行里面的代码逻辑
    print(next(res)) # 准备开始... None
    print(next(res)) # Jim Green: yield挂起后继续执行...None
    print(next(res)) # # Jim Green: yield挂起后继续执行...None

- 实例2:接收 send()的值

    def action(name):
        print('准备开始...')
        while True:
            x = yield
            print('{0}---{1}: yield挂起后继续执行...'.format(name, x))
            print(123)

    res = action('Jim Green')

    print(res) # <generator object action at 0x00000137FEB32F10>
    print(next(res)) # 准备开始... None
    print(next(res)) # Jim Green: yield挂起后继续执行...123...None
    res.send('发送消息1') # Jim Green---发送消息1: yield挂起后继续执行...123...
    res.send('发送消息2') # Jim Green---发送消息2: yield挂起后继续执行...123...
    print(next(res)) #  # Jim Green: yield挂起后继续执行...123...None


    res.close() # 关闭以后,执行下面这句,会报错了 StopIteration
    res.send('发送消息3')

- 小结:使用 yield 的好处

    - 使程序暂时'挂起',然后可以执行其他程序的逻辑,等需要该程序时,再释放(比如获取到其他程序的结果,然后传给yield继续执行)

yield 的补充理解

def foo():
    print("starting...")
    while True:
        res = yield 4 # y = return 4 这种写法本身就会报错
        # print(res)
        print("res:",res)

g = foo() # 初始化
print(next(g))
print("*"*20)
print(next(g))

'''

starting...
4 # 执行到这步时,返回4,打印出来,此时 res并没有存储值,因为程序暂停了
********************
res: None # 程序继续,既然 res没有存储值,当然是None
4

'''

- send()示例

    def foo():
        print("starting...")
        while True:
            res = yield 4
            print("res:",res)

    g = foo()
    print(next(g))
    print("*"*20)
    print(g.send(7))

    '''

    starting...
    4
    ********************
    res: 7 # 使用yield接收send传过来值,并赋值给res,由于send()中包含next()方法,继续执行循环...
    4

    '''
  • 小程序全局配置的两种方式(看情况选择)

    • 利用'app.js',创建全局变量,其他模块再从这边取

      // app.js App({ ...... globalData: { # 创建全局变量 userInfo: null } })

      运用

      var app = getApp(); # 获取 app.js的配置 ...... wx.request({ ...... success: function(res){ if(res.data.status){ # 给 globalData 赋值 app.globalData.phone = res.data.data.phone; ...... } })

    • 自定义'config.js'配置,其他模块需要调用时,导入即可

      config.js

      const rootUrl = 'http://127.0.0.1:8000/api/'; # 声明常量

      module.exports = { newsApi:rootUrl+'news/', # 导出配置 commentApi:rootUrl+'comment/' };

      index.js

      var api = require('../../config/api.js') # 导入 Page({ ...... onLoad: function (options) { wx.request({ url: api.newsApi,


screwdriver benchmark parallel payload



匿名函数

- 应用场景:一次性调用,搭配其他函数使用

-调用方式

    - 方式一(1%的使用场景)

    (lambda x, y: x + y)(1, 2)

    - 方式二(没必要,和普通函数有区别???)

    res = lambda x,y:x+y
    print(res(1,2))

常用函数介绍

- max: 获取最大值,返回key(可以指定参数key的排序依据,从而返回不同的key)

    salary = {
        'JimGreen':3000,
        'KateGreen':3500,
        'LiLei':3200,
        'HanMeiMei':3900
    }

    print(max(salary)) # LiLei(默认按照key排序,涉及到字符串的比较方式)


- 传入 key,指定排序的依据

    salary = {
        'JimGreen': 3000,
        'KateGreen': 3500,
        'LiLei': 3200,
        'HanMeiMei': 3900
    }


    def func(key): # key由max帮你传
        return salary[key]


    print(max(salary, key=func)) # HanMeiMei

    - 这里也可以使用匿名函数

    salary = {
        'JimGreen': 3000,
        'KateGreen': 3500,
        'LiLei': 3200,
        'HanMeiMei': 3900
    }

    print(max(salary, key=lambda k: salary[k]))

- sorted:排序

    - 语法

        sorted(...)
        sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list

    - 基础应用:传入可迭代对象即可

        l = sorted([5,6,1,2])
        print(l) # [1, 2, 5, 6]

    - 根据 key 排序:以下实例,根据元素的长度,进行排序

        l = [{'name': 'JimGreen', 'age': 18}, {'name': 'JimGreen', 'age': 18, 'sex': 'male'}, {}, {'name': 'JimGreen'}]
        new_l = sorted(l,key=lambda k:len(k))
        print(new_l) # [{}, {'name': 'JimGreen'}, {'name': 'JimGreen', 'age': 18}, {'name': 'JimGreen', 'age': 18, 'sex': 'male'}]

- zip:压缩,把序列之间的元素,对应在一起

    l1 = [1, 2, 3, 4]
    l2 = [5, 6, 7, 8]

    l3 = zip(l1,l2)
    print(list(l3)) # [(1, 5), (2, 6), (3, 7), (4, 8)]


- map: 依据提供的函数,对可迭代对象的每一个元素,作处理

    - 基础实例

        l = [1, 2, 3, 4]

        res = map(lambda item: item ** 2, l) # 传入单个序列
        print(res) # <map object at 0x0000023A21DDA518>
        print(list(res)) # [1, 4, 9, 16]


        l1 = [1, 2, 3, 4]
        l2 = [5, 6, 7, 8]

        res = map(lambda x, y: x + y, l1, l2) # 传入两个序列
        print(list(res)) # [6, 8, 10, 12]

    - 讲字符串转为list

        l3 = map(int,'1234')
        print(list(l3)) # [1, 2, 3, 4]


- filter:过滤

    - 语法

        filter(function or None, iterable) --> filter object

    - 示例

        l = ['king','other','book','ling']
        res = filter(lambda name:name.endswith('ing'),l)
        print(list(res)) # ['king', 'ling']

- reduce:对参数序列中元素进行累积

    - 语法:

        reduce(function, sequence, initial=None)

    - 实例:

        from functools import reduce

            res = reduce(lambda x,y:x+y,[1,2,3,4] )
            print(res) # 10

版权声明:如无特殊说明,文章均为本站原创,转载请注明出处

本文链接:http://example.com/article/python_lack/

许可协议:署名-非商业性使用 4.0 国际许可协议