列表浅拷贝与深拷贝
- 引入场景 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 国际许可协议