西区代码小仓库
type: channel
link: https://lisper517.top/
description: lisper517的个人博客
items: 投资策略-定投
items: 《深度学习入门 基于Python的理论与实现》-斋藤康毅（笔记）
items: 按键精灵（python加强版）
items: 如何正确用Python截取屏幕
items: JavaScript入门（源自runnoob）
items: html入门（源自runnoob）
items: 《MySQL必知必会》-Ben Forta（笔记）
items: 《Python网络数据采集》-Ryan Mitchell（笔记）
items: 《Learn Python the Hard Way/笨办法学python》（第三版）-Zed Shaw（笔记）
items: python中函数的多层嵌套与nonlocal

投资策略-定投
type: item
date: 2025-12-20T13:34:00+00:00
description: 第一章 定投的理论基础 第二章 定投实践 第三章 辅助工具本文的目的是描述定投的投资策略。本文首发于个人博客https://lisper517.top/archives/4264/，转载请注明出处。本文内容来自各种网络资料，个人总结。任何投资都有风险，本文不构成任何投资建议。理财产品收益率超过6%就要打问号，超过8%很危险，超过10%就要做好损失全部本金的准备（郭树清，陆家嘴金融论坛，2018-06-14）。一定用闲钱投资，不要拿马上急用的钱、贷款借来的钱投资。第一章 定投的理论基础一、定投的概念定投即“定期定额投资”，指在固定的时间（如每月1日，每周一，或者每天），以固定的金额（如每月1000元），投资到指定的同一投资标的（如某支指数基金）中。定投像一种“理财储蓄计划”，让你忽略市场短期波动，通过长期、持续的投入来平滑成本、积累资产。一、定投的特点1.淡化择时定投假设市场总是在波动，不去预测市场的高点或低点，而只需严格按照定投计划操作，避免了“追涨杀跌”。2.平均投资成本在价格高时，定投能买到较少的份额，但已持有的部分在上涨；在价格低时，虽然持有的部分下跌，但定投能买到更多的份额。综合下来看，定投降低了平均购入成本。另外，对于资金不充裕的人来说，无法一次性拿出大量本金，定投也使资金投入更平滑。3.复利效应4.强制储蓄对于年轻人来说，定投也可以避免乱花钱。当然，也不能排除定投亏钱的可能。第二章 定投实践一、选择投资标的定投最适合的是长期上涨、但短期有波动的资产。1.首选宽基指数基金，如纳斯达克100、标普500这些指数的基金（难度稍微大一点的有沪深300、中证500、上证50、科创50、创业板指等）。2.次选行业、主题指数基金，如消费、医药、科技、新能源、AI等。3.再次选其它主动管理型基金，根据基金经理风格不同而有变化，可能重仓某支个股、板块，也可能一些经理喜欢分散投资。4.其它国债，收益稳定但较低；个股期货，风险太高。笔者的建议是尽量分散投资，即有稳健的国债，也可以适当加一些激进的投资。目前（2025-12-20）关注的有：（1）宽基指数，纳斯达克100、标普500、沪深300、上证50等。前两者关注更多，算风险中等。 （2）贵金属，黄金白银等。黄金近几年涨疯了，目前可能处于高位，应该算风险较大。 （3）现金流ETF，一些现金流充沛的公司，算风险较大。 （4）红利ETF，稳定高分红的公司，也称低波红利（低波动性），算风险较低。但是投资此类ETF需要做好长期打算，五年十年。 （5）短融ETF，短期债券（消费债等等），和国债的风险差不多。 （6）国债，风险最低。风险可以自己评估，最简单的道理：收益越高、风险越大。不要把鸡蛋放在一个篮子里，比如所有资金只拿1/3投资，其它2/3留作它用；在这1/3里，又作如下划分：（1）宽基指数投50%。（2）红利低波，20%（3）现金流，10%。（4）贵金属，10%。（5）短融，5%。（6）国债，5%。上面只是随便举例，不构成投资建议。总之，通过合适搭配，最终目标是跑赢通胀，使所有加和、总的年化收益达到5%，或者8%，甚至10%。二、选择投资平台在支付宝、银行等平台交易称为场外交易（还有京东、且慢、天天基金等），各种券商平台交易则称为场内交易。一般普通人投资在支付宝即可，购入手续费打一折（0.1%左右）。场外交易的优点是方便快捷，可设置自动扣款，省心。缺点有：①整体费率更贵。包括申购费（1.2%左右），管理费、托管费（加起来0.6-1%不等，看具体基金）等。②交易不自由，比如可能有单日买入限额，T+2（发起买入操作后需要再过2天才能实际入仓）等。但是可以设置每日定投规避限额，并且定投本来也是需要长期持有的，笔者感觉影响不大。如果选择场外交易，买的一般都是带“联接”的，长期持有的话选后缀为A的，短期操作选C类。A类的管理费、托管费更低，但买入费更高，而且如果持有时间短就想卖的话还要收费（一般需要持有1周到1年，卖出时才不会收手续费，这也是为了鼓励长期持有）。场内交易的优点是综合费率低（前提是）。缺点有：①整体费率更便宜。前提是能申请到万分之0.5手续费、5块起收的券商账户，否则算下来可能不如支付宝的性价比。②有溢价，一般溢价在4-8%。溢价8%就不适合买入。当然，卖出的时候选择合适时机，也能吃到这部分溢价。③实时交易，不限额、不限T+N。④各家券商平台只能买到自家产品，可能需要下多个APP。三、设置自动扣款每日，每周，或者每月自动购买即可。设置完后就不要再频繁操作，反而容易追涨杀跌、亏钱。定投最考验的是定力，选择了对的标的，就要坚定执行定投计划，以一年、三年甚至五年十年为期望，短期下跌10%，甚至30%、50%都是可能的。不要被某一处损失动摇，比如贵金属跌了，其它涨了，就卖出所有贵金属。目标是总…

《深度学习入门 基于Python的理论与实现》-斋藤康毅（笔记）
type: item
date: 2025-12-17T14:48:00+00:00
description: 步骤/目录： 无本文首发于个人博客https://lisper517.top/index.php/archives/4260/，转载请注明出处。本文的原文写作日期为2020年11月17日，主要目的是总结《深度学习入门 基于Python的理论与实现》。笔者的毕业论文有很多东西来自这本书。下面的内容有些缩进或者图片缺失，可以参考 原word文档 。本书主要用numpy来处理运算，用matplotlib将结果可视化。对于没有基础的人十分友好，只需要高中的线代知识就可以看懂。 1.x=x.flatten() 将矩阵及张量转换为一维数组。x>15，结果得到一个由True和False组成的一维列表，x[x>15]即可输出所有大于15的成员。 矩阵与一维数组的*乘，（数组长度与矩阵列数相同）将一维数组扩张为矩阵形状后简单相乘，符合交换率，符号为*； 矩阵与数组dot乘，（数组长度与矩阵列数相同）将一维数组与每行对应索引相乘求和，得到一维数组，长度为矩阵的行数：如[[1, 2], [3, 4], [7, 8]] dot [5,6]，则得[1*5+2*6, 3*5+4*6,7*5+8*6]，不符合交换律，用np.dot计算。 一次绘图流程：p42 2.感知机：接受一个或多个输入，输出一个信号。有多个输入时，可以给各个输入配置权重。机器学习就是人给机器一些数据，机器根据这些数据选出权重的过程。 P56从图像上，感知机是一条直线，有局限性。叠加多个感知机可以构造类似曲线。 3.对于单层感知机，实际上有两个函数，比如首先有y=b+x1*w1+x2*w2，其中b为偏置，w1、w2为权重；然后通过激活函数，比如h(x)=1或0（当y<=0时为0，否则为1。这种函数的输出是跳跃的，可称为阶跃函数）。若把激活函数换成其他形式，就接近神经网络的概念了。常用的一个激活函数（sigmoid函数）：1/(1+exp(-x))，其中exp(-x)为e的-x次方。 接受numpy数组为参数的阶跃函数见p69。 激活函数也可以使用ReLU函数，其在x<=0时输出0，在x>0时则为线性关系。P74 对于输出层的激活函数，如果是分类问题（类似阶跃函数）用softmax函数，回归问题（连续输出数值）用恒等函数。P89 softmax函数的输出是连续的，总和为1，可以看作概率。为了节省算力，对未知模型进行预测时通常也可以省略输出层的softmax激活函数（接受数据进行学习时可以不省略）。 在分类问题中，输出层的神经元数量通常等于类别的数量。哪个神经元的输出最大，就会归类为该类别。 4.正规化：将数据进行处理，使其限制在某个范围内。正规化是一种预处理。 批处理：相同的神经网络，多个输出，多个结果。批处理可以大大加快运算速度。P101 5.损失函数：描述当前神经网络与测试数据（即监督数据）在多大程度上不拟合。一般可用均方误差函数和交叉熵。均方考虑了非正确解、越接近0（越小）越好，交叉熵只包含正确解、越接近0（越小）越好。 机器学习就是要使得损失函数值最小。如果训练数据太多，可以从中随机选择部分数据来学习，称为mini batch。 不用精确度作为评价标准，因为要设定参数的导数（变化梯度），如果用精确度为指标，容易导致导数为0，参数无法更新（精确度常常是跳跃的，微调无法产生影响，而损失函数是连续变化的）。这也是sigmoid函数优于阶跃函数的地方（激活函数）。 对于矩阵，y[0,2]的写法等同于y[0][2] 梯度指示的方向是损失函数减少量最多的地方，不一定指向损失函数值最小的地方。所以，机器学习可能会陷入局部最小值、鞍点或者学习平原。 鞍点处的梯度也为0，比如一个马鞍形曲面，(0,0,0)处的形状就很像马鞍。 梯度，就是一个一维数组。一个函数有多个输入，那么梯度就是这个多维函数（在某一点处）的导数。梯度数组的大小和输入多少相等，意义是对每一个输入，在保持其他输入不变时求该输入的导数，最终组成一个导数数组。为了使损失函数减小，需要沿负梯度方向下降。 6.反向传播法算梯度的速度比微积分法快许多，主要应用了复合函数的求导（相乘）。 7.有时SGD（随机梯度下降），即沿着梯度最大的地方下山的方法，不一定能最快下山。还有其他一些方法。 Momentum（动量法），如果某一方向上的梯度较小，但是持续很久，就适合用这种方法。模拟静止小球在山中的运动，某一方向累计的梯度会给小球积累该方向的速度，于是在该方向上移动越来越快。 AdaGrad（Adaptive适应梯度法），对梯度中的每一个导数都有一个学习率，该学习率还会不断衰减。AdaGrad是通过记录过去所有梯度的平方和实现的，最终学习率会衰减到0。不想让学习率衰减太快可以用RMSProp法，其会更多地考虑最近的梯度、逐渐减小久远梯度的权重。 Ada…

按键精灵（python加强版）
type: item
date: 2025-12-17T14:38:00+00:00
description: 步骤/目录： 无本文首发于个人博客https://lisper517.top/index.php/archives/4259/，转载请注明出处。本文的原文写作日期为2020年10月22日，主要目的是用Python重构按键精灵。主体程序，主要是一些功能的实现，具体应用需要自己写。写的比较乱：import win32gui, win32api, win32con, win32ui import time from time import sleep import random from random import uniform import logging from logging import info, warning, error from config import VK_CODE import copy import cv2 as cv import traceback # mode为test意为调试模式，real则为实际应用 # In 'test' mode, it will print some hidden info for Debug mode = 'test' # 模式图的存储路径 # The save path of pattern pics pattern_path = 'yourpath\\' # 设置logging的书写格式 # Setting logging configs logging.basicConfig( level=logging.DEBUG, format= '%(lineno)d : %(asctime)s : %(levelname)s : %(funcName)s : %(message)s', filename='yourpath\\log{}.txt'.format( time.strftime('-%Y-%m-%d')), filemode='w') # 用当前时间初始化随机数 # Set random seed random.seed(time.time()) def Get_PosAndHwnd(hwnd=0, ClassName=None, TitleName=None): '''接受句柄、类名、标题名，返回第一个匹配的窗口位置和句柄。 Accepts Handle, ClassName or TitleName of a window, returns the rect-pos of the first window that matches. Args: hwnd: 目标句柄 target handle. ClassName: 目标窗口类名 target ClassName. TitleName: 目标窗口标题 target TitleName. Returns: x1, y1, x2, y2, hwnd 前四个参数描述窗口在显示器中的位置，hwnd为句柄。 x1-y2 describes the pos of the window in screen, last arg is the handle. ''' try: if hwnd == 0: hwnd = win32gui.FindWindow(ClassName, TitleName) x1, y1, x2, y2 = win32gui.GetWindowRect(hwnd) info('找到窗口，句柄：{}，标题名：{}，类名：{}，坐标：{}'.format( hwnd, win32gui.GetWindowText(hwnd), win32gui.GetClassName(hwnd), (x1, y1, x2, y2))) return x1, y1, x2, y2, hwnd except: global mode if mode == 'test': traceback.print_exc() elif mode == 'real': error('Get_PosAndHwnd 出现错误') def Activate_Hwnd(hwnd): '''激活指定句柄的窗口。每次转换时使用。 Activates the window with the matching hwnd. Args: hwnd: 目标句柄 target handle. Returns: No return. ''' try: win32gui.SendMessage(hwnd, win32con.WM_ACTIVATE, win32con.WA_ACTIVE, 0) # WA_CLICKACTIVE为通过鼠标激活，WA_ACTIVE为鼠标以外的东西（如键盘）激活，WA_INACTIVE为取消激活 # WA_CLICKACTIVE …

如何正确用Python截取屏幕
type: item
date: 2025-12-17T14:33:00+00:00
description: 步骤/目录： 无本文首发于个人博客https://lisper517.top/index.php/archives/4257/，转载请注明出处。本文的原文写作日期为2020年10月21日，主要目的是用Python截取屏幕。最近需要对窗口截图，看到了以下文章：https://www.cnblogs.com/Evan-fanfan/p/11097850.html其中有些错误（乱写文章害人不浅啊）。经过我2天实验，大概搞清楚了3个关键api的用处。注释和代码如下：# 根据句柄、截图位置和图片路径，对窗口的客户区截图并存到指定位置 # GetDC一类的需要用ReleaseDC释放，CreateDC一类的用DeleteDC释放，DeleteObject则删除一个逻辑笔、画笔、字体、位图、区域或者调色板， def ClientRect_PrtSc(hwnd, area=None, filename=''): try: hwnd = hwnd if filename == '': filename = 'C:\\Users\\tadio\\Desktop\\helper\\pics\\targets\\{}.bmp'.format( hwnd) hwndDC = win32gui.GetDC( hwnd) # 获取窗口的设备上下文Device Context。GetWindowDC包括了非客户区，而GetDC仅为客户区 mfcDC = win32ui.CreateDCFromHandle(hwndDC) # 获取mfcDC saveDC = mfcDC.CreateCompatibleDC() # 创建可兼容DC saveBitMap = win32ui.CreateBitmap() # 创建bitmap以保存图片 '''MonitorDev = win32api.EnumDisplayMonitors( None, None) # 获取显示器信息，枚举显示器，笔记本据说可能有问题''' x1, y1, x2, y2 = win32gui.GetClientRect( hwnd) #GetClientRect获取客户区窗口位置，GetWindowRect获取整个窗口的位置信息 x, y, w, h = (0, 0, 0, 0) if area == None: x = 0 y = 0 w = x2 - x1 h = y2 - y1 else: x, y, m, n = area w = m - x h = n - y saveBitMap.CreateCompatibleBitmap(mfcDC, w, h) # 为bitmap开辟空间 # 对saveBitMap.CreateCompatibleBitmap(mfcDC, w, h)的理解： # 1.mfc相当于一个虚拟屏幕。这里的参数w和h决定了这个屏幕的大小。 # 2.屏幕的初始状态是黑色，每个坐标都是#000000 # 3.之前有mfcDC = win32ui.CreateDCFromHandle(hwndDC)，又有hwndDC = win32gui.GetDC(hwnd) # mfcDC和hwnd窗口之间建立了某种关联，可以将hwnd窗口中的图像放到虚拟屏幕上 saveDC.SelectObject(saveBitMap) # 将截图保存到saveBitMap中 saveDC.BitBlt((0, 0), (w, h), mfcDC, (x, y), win32con.SRCCOPY) # 对saveDC.BitBlt(坐标1, (w, h), mfcDC, 坐标2, win32con.SRCCOPY)的理解： # BitBlt的功能大概是把从hwnd窗口截到的图放到虚拟屏幕上，信息转入saveDC。 # 1.坐标1是针对窗口截图的，指定截图放在黑色背景上的位置（指定左上角） # 2.w和h窗口截图的长宽，而坐标2指定了开始截图的位置 # 这两个参数决定了从hwnd窗口的哪里截图、截多大的图 # 3.mfcDC已经和hwnd窗口建立了关联，所以不需要指定虚拟屏幕从哪个窗口获得截图 # 4.SRCCOPY意为将截图直接拷贝到虚拟屏幕中 # 接下来的saveBitMap.SaveBitmapFile(saveDC, filename)则是对虚拟屏幕截图并保存到指定位置 saveBitMap.SaveBitmapFile(saveDC, filename) # 清除数据 win32gui.DeleteObject(saveBitMap.GetHandle()) saveDC.DeleteDC() mfcDC.DeleteDC() win32gui.ReleaseDC(hwnd, hwn…

JavaScript入门（源自runnoob）
type: item
date: 2025-12-17T14:21:00+00:00
description: 步骤/目录： 无本文首发于个人博客https://lisper517.top/index.php/archives/4252/，转载请注明出处。本文的原文写作日期为2020年9月24日，主要目的是初步了解JavaScript（源自runnoob）。下面的内容有些缩进或者图片缺失，可以参考 原word文档 。https://www.runoob.com/js/js-tutorial.html 1.js直接写入输出流： 设置一个按钮，对时间做出反应： 点我! 用js改变html内容： JavaScript 能改变 HTML 元素的内容。 点击这里 或者改变图片（这里可以使用?:运算符）： 验证输入： 点击这里 2.js应该位于 之间，放在 或 里。通常情况下都放在head里或者统一放在页面底部（脚本可以写在调用处之后）。也可以从调用外部脚本，修改script的src即可： 标签的innerHTML属性，即内容，可以赋值更改。 Document.write在页面加载后使用则会覆盖页面。 3.js输出： window.alert()弹出警告框，document.write()将内容写到HTML文档，innerHTML写出到标签的内容，console.log()写入到浏览器的控制台。 Js字面量：整数、小数、科学计数（123e5）、字符串（单双引号均可）、数组（[]括起来）、对象（由键值对组成）、函数（用function声明）。 声明变量用var。所有皆var（块中的变量可用let。如果不加var或let，则默认为全局变量。花哨一点可用用var x = new 类型(值)）。语句用;分隔（可选）。注释用//和/*。js对大小写敏感。Try对应catch，throw对raise。可用\表示下一行接续（有条件）。Js逐行执行。标签有this指针。 4.HTML常见事件： 事件 描述 onchange HTML 元素改变 onclick 用户点击 HTML 元素 onmouseover 用户在一个HTML元素上移动鼠标 onmouseout 用户从一个HTML元素上移开鼠标 onkeydown 用户按下键盘按键 onload 浏览器已完成页面的加载 5.字符串对象有length方法。其他常用的还有concat、indexOf、match（re匹配）。 ===操作要求类型和值都相同，==则先转换为同类型，只比较值。相对有!=和!==。 Js中也有switch，和c++中一样。这里的switch用的是===判断。 Break或continue可以后接具体的block名。 6.在 JavaScript 中有 6 种不同的数据类型： string number boolean object function symbol 3 种对象类型： Object Date Array 2 个不包含任何值的数据类型： null undefined 6.js中的re：格式为 /正则表达式主体/修饰符(可选) 比如i修饰符，表示不区分大小写。 其他修饰符： i 执行对大小写不敏感的匹配。 g 执行全局匹配（查找所有匹配而非在找到第一个匹配后停止）。 m 执行多行匹配。 search方法和replace方法都可用re。 元字符： \d 查找数字。 \s 查找空白字符。 \b 匹配单词边界。 \uxxxx 查找以十六进制数 xxxx 规定的 Unicode 字符。 Re有test方法，用来检验一个字符串是否含有自己。 Re详见https://www.runoob.com/jsref/jsref-obj-regexp.html 可用js验证表单。或者在input标签中添加required="required"属性来自动验证非空。Html5中新增了约束验证。 7.异步函数：在网页上执行一些时间较长、当前用不到的事情，比如读取大文件或者发出网络请求，可用在主线程之外用子线程，同时进行。具体用法是setTimeout(函数名，ms时间)，执行时启动一个独立于主线程的子线程，等待函数执行一定时间。 对于嵌套setTimeout，可用promise将其转变为顺序结构。 更多内容见后。以上内容仅用于初步看懂js。

html入门（源自runnoob）
type: item
date: 2025-12-17T14:15:00+00:00
description: 步骤/目录： 无本文首发于个人博客https://lisper517.top/index.php/archives/4250/，转载请注明出处。本文的原文写作日期为2020年9月22日，主要目的是初步了解html（源自runnoob）。下面的内容有些缩进或者图片缺失，可以参考 原word文档 。Runnoob可以提供html的基本知识。 参考手册：https://www.runoob.com/tags/html-reference.html 1.Html不认识\t\n等，都会输出为空格。 （不分大小写）为标准网页声明，位于所有标签之前，在支持html的浏览器中会被解释为网页使用html5编码。 是页面的根元素， 一般包含了文档的meta数据，比如编码格式（一般对于中文可以写charset=”UTF-8”或者”GBK”）； 为网页标题， 为可见内容， 到 为标题， 为段落。链接在标签的href属性中，图像在 中，后面规定名称和尺寸，如 。 myweb my first html my first html instance 按f12，在elements中可找到标签布局。 关于图片的进一步解释： 1、*.html 文件跟 *.jpg 文件(f盘)在不同目录下： 2、*.html 文件跟 *.jpg 图片在相同目录下： 3、*.html 文件跟 *.jpg 图片在不同目录下： a、图片 *.jpg 在 image 文件夹中，*.html 跟 image 在同一目录下： b、图片 *.jpg 在 image 文件夹中，*.html 在 connage 文件夹中，image 跟 connage 在同一目录下： 4、如果图片来源于网络，那么写绝对路径： 关于href和src： href 是 Hypertext Reference 的缩写，表示超文本引用。用来建立当前元素和文档之间的链接。常用的有：link、a。例如： 浏览器会识别该文档为 css 文档，并行下载该文档，并且不会停止对当前文档的处理。这也是建议使用 link，而不采用 @import 加载 css 的原因。 src 是 source 的缩写，src 的内容是页面必不可少的一部分，是引入。src 指向的内容会嵌入到文档中当前标签所在的位置。常用的有：img、script、iframe。例如: 当浏览器解析到该元素时，会暂停浏览器的渲染，直到该资源加载完毕。这也是将js脚本放在底部而不是头部得原因。 简而言之，src 用于替换当前元素；href 用于在当前文档和引用资源之间建立联系。 1. 表示换行，没有结束标签。有些元素为空元素，以开始标签的结束而结束（有些元素只有一个开始标签），但考虑到未来标准，建议后面还是写个 。大多数情况下，即使不写结束标签也可以，但这样不应当。目前标签大小写无所谓，但应该尽量小写。 在开始标签中设置属性，也是尽量小写，单双引号无所谓。Class属性中可为元素定义多个或一个类名（从样式文件引入），id则是唯一的，style规定样式，title描述元素的额外信息。 Html中的标签： New : HTML5新标签 标签 描述 定义注释 定义文档类型 定义超文本链接 定义缩写 定义只取首字母的缩写，不支持HTML5 定义文档作者或拥有者的联系信息 <applet> HTML5中不赞成使用。定义嵌入的 applet。 定义图像映射内部的区域 New 定义一个文章区域 New 定义页面的侧边栏内容 New 定义音频内容 定义文本粗体 定义页面中所有链接的默认地址或默认目标。 <basefont> HTML5不支持，不赞成使用。定义页面中文本的默认字体、颜色或尺寸。 New 允许您设置一段文本，使其脱离其父元素的文本方向设置。 定义文字方向 定义大号文本，HTML5不支持 定义长的引用 定义文档的主体 定义换行 定义一个点击按钮 New 定义图形，比如图表和其他图像,标签只是图形容器，您必须使用脚本来绘制图形 定义表格标题 HTML5不支持，不赞成使用。定义居中文本。 定义引用(citation) 定义计算机代码文本 定义表格中一个或多个列的属性值 定义表格中供格式化的列组 <command>New 定义命令按钮，比如单选按钮、复选框或按钮 New 定义选项列表。请与 input 元素配合使用该元素，来定义 input 可能的值。 定义定义列表中项目的描述 定义被删除文本 New 用于描述文档或文档某个部分的细节 定义定义项目 New 定义对话框，比如提示框 HTML5不支持，不赞成使用。定义目录列表。 定义文档中的节 定义列表详情 定义列表中的项目 定义强调文本 New 定义嵌入的内容，比如插件。 定义围绕表单中元素的边框 New 定义 元素的标题 New 规…

《MySQL必知必会》-Ben Forta（笔记）
type: item
date: 2025-12-17T14:07:00+00:00
description: 步骤/目录： 无本文首发于个人博客https://lisper517.top/index.php/archives/4248/，转载请注明出处。本文的原文写作日期为2020年9月20日，主要目的是总结《MySQL必知必会》。下面的内容有些缩进或者图片缺失，可以参考 原word文档 。本书的内容十分基础，建议直接看原文，或者忘记语法的时候查阅。初读的时候可以先粗略读一遍，然后把书上的每个例子都打一次。附录c可以作为复习使用。 1.可以创建多个数据库，每个数据库可包含多个表。同一个库中的表不能重名。Schema模式，指库和表的组织形式，可以用describe 表 来查看。表分为行、列，尽量把列细分（数据细分）方便查找；每行数据有一个主键来作为唯一标识，虽然有些数据不一定需要主键才能区分，但一般都应该定义一个主键，Mysql要求任意两行的主键不同，且每行都有一个非NULL的主键，主键也可以定义在多个列上。 定义主键时应该做到：不重用主键（删了以后不重用）；用不可能变的值作为主键；不修改主键值。 除了主键，还可以定义外键，将表中数据关联到其他表。 2.mysql administrator 和 mysql query browser 提供了GUI，可以考虑下载。由于mysql8有一些改动，可能遇到问题。 进入数据库：在cmd输入mysql -uroot -h localhost -p（先将mysql加入环境变量），接下来要求输入密码。如果连接本地服务器，可以省略-h参数。 Mysql命令行中，每个语句末最好加上; mysql不区分大小写，但很多人喜欢将关键字大写。 Mysql不会识别换行符，可以将命令分行写出，便于阅读。 在mysql命令行下，用show命令显示库和表，也可以用show columns from 表名 显示表内列的信息，或者用更简洁的describe 表名。 用help 命令名 获取相关信息。 Show的其他用法：  SHOW STATUS，用于显示广泛的服务器状态信息；  SHOW CREATE DATABASE和SHOW CREATE TABLE，分别用来显示创 建特定数据库或表的MySQL语句；  SHOW GRANTS，用来显示授予用户（所有用户或特定用户）的安 全权限；  SHOW ERRORS和SHOW WARNINGS，用来显示服务器错误或警告消息。 3.select命令返回的顺序可能变化（为底层存储顺序），因为mysql在数据删除后可能重用空间。 如果列中的值有重复，可使用distinct关键字指明查询不同值。Distinct会用于所有列，比如指定了多个列，如果查找到一行，其每个列的数据同前面某行完全一样，那么就不会打印出。 在末尾加limit a,b（a和b为数字），意为指定从行a开始（不包括行a，第一行为0）最多打印b个结果。 用.表示库和表的从属关系。 用order by 语句可以指定用某一列数据排序。该列可以不在显示出来的列中。Order by 后跟多个列时，表示按权重排名。在最后加desc表示降序（对多个列需要分别写一次desc）。Limit必须在order by 之后。Order by 应在where后。 Where：使用between a and b指定数值范围（返回结果包括a和b）。Is null 检索值为NULL的列。检索非某值时不会返回值为NULL的行。 And比or优先。用()分离不同条件，且应该尽量多用()。 In用法类似于python元组。In还可以嵌套where。 Not可以用来否定条件，比如对in、between、exists取反。 正则表达式、通配符：必须用like。 %表示任意字符任意次数（含0次）。%不匹配NULL。 _表示单个字符单次。 通配符搜索比较慢，尤其是放在开头。 用regexp代替like，表示后面跟的是re。不加^和$，regexp默认全部或部分匹配，而like只能全部匹配。Regexp后加binary可区分大小写。 Mysql中的re转义字符要求写成\\而不是单个\。 写的时候要[[]] 写完的re可以用select 字符串 regexp re表达式 的格式来测试，0为未找到。 4.计算字段，通过表中数据经过一定运算得出的数据列，不存在于表中。一般在服务器上就计算出相应数据并返回（因为DBMS的处理快），客户机上并不能区分计算字段和表中数据。 为了使客户机能引用计算字段，需要将计算字段赋予别名，select 计算字段 as 别名 from ... As中，多个计算字段要分别写多个as、赋予不同的别名。 拼接：mysql用conca()函数实现拼接（其他sql用+或||等）。 删掉空格可以用RTrim、LTrim或者Trim函数。 Select省…

《Python网络数据采集》-Ryan Mitchell（笔记）
type: item
date: 2025-12-17T14:05:01+00:00
description: 步骤/目录： 无本文首发于个人博客https://lisper517.top/index.php/archives/4247/，转载请注明出处。本文的原文写作日期为2020年9月17日，主要目的是总结《Python网络数据采集》。下面的内容有些缩进或者图片缺失，可以参考 原word文档 。1.本书使用标准urllib模块和非标准模块bs4模块： from urllib.request import urlopen from bs4 import BeautifulSoup html = urlopen("http://www.pythonscraping.com/pages/page3.html") bsObj = BeautifulSoup(html) 2.find_all()方法相关： find_all(name=None, attrs={}, recursive=True, text=None, limit=None, **kwargs) method of bs4.BeautifulSoup instance 第一个参数name为标签名，为None时可匹配所有标签名； 第二个为标签属性，常以字典形式给出； 第三个为是否递归查找，除非十分了解网页格式且有时间要求，一般情况下都取True； 第四个为匹配标签内容； limit为查找返回个数限制，为1时该方法等同find方法； 最后是一些其他参数。 3.html格式相关： 子节点（children）和后代节点（descendant），子节点仅为下一级的标签，后代节点包含所有下级标签： for child in bsObj.find("table",{"id":"giftList"}).children: print(child) 这些相关节点都是包含空格、换行的，处理时务必去掉 兄弟标签：next_siblings为后续的所有同级标签，previous_siblings相反。这两个都有去掉s的形式。 父标签与祖先标签：parent和parents 4.常用re符号： 5.用attrs方法返回一个标签的所有属性（字典形式） 6.scrapy应用：自学 7.API，应用编程接口，有严格的语法，用XML或json表示数据。 HTTP常用方法：get，请求网页信息；post，用户提交信息；put，请求更新某个数据；delete，请求删除某个数据。 8.使用twitter库获取推文、更新推文等；利用google、baidu提供的API。 9.用urllib.request.urlretrieve下载文件 10.学习mysql mysql基础命令： net start mysql 启动sql网络服务；CREATE DATABASE scraping 创建数据库；USE scraping 使用数据库； >CREATE TABLE pages (id BIGINT(7) NOT NULL AUTO_INCREMENT, title VARCHAR(200), content VARCHAR(10000), created TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id)); 用以上头创建数据库中的表； > INSERT INTO pages (title, content) VALUES ("Test page title", "This is some te st page content. It can be up to 10,000 characters long."); 向表中插入数据； >SELECT * FROM pages WHERE title LIKE "%test%"; 查找数据； 删除只需要把对应的SELECT换成DELETE即可。记得先确认，加上WHERE。 >UPDATE pages SET title="A new title", content="Some new content" WHERE id=2; 更新数据。 ALTER DATABASE scraping CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; 将scraping数据库的字符集从utf8mb4改为utf8mb4_unicode_ci。 用pymysql在python中使用mysql： import pymysql conn = pymysql.connect(host='127.0.0.1', user='root', passwd='aboutime', db='mysql')# 创建连接对象 cur = conn.cursor()# 创建游标对象 cur.execute('U…

《Learn Python the Hard Way/笨办法学python》（第三版）-Zed Shaw（笔记）
type: item
date: 2025-12-17T13:51:00+00:00
description: 步骤/目录： 无本文首发于个人博客https://lisper517.top/index.php/archives/4242/，转载请注明出处。本文的原文写作日期为2020年9月17日，主要目的是总结《Learn Python the Hard Way/笨办法学python》（第三版）。下面的内容有些缩进或者图片缺失，可以参考 原word文档 。总结：这本书适合自学能力较强的，或者有一定基础的人自学。 1.格式化输出：%s用于string（基于str()），%r用于debug（基于repr()，原封不动显示输出，双引号转换为单引号），%d用于整数。format更先进。 2.sys.argv：脚本接受的参数列表。[0]为脚本路径。 3.文件操作：f=open(文件名,’w’)。常用方法：f.close()、read()、readline()、truncate()、write(字符串)等。注意方法的参数。 4.f.seek(整数)将读/写指针放到指定位置。 5.str.split(‘ ’)以空格为标志分割str，返回列表。 列表.pop(x)弹出（即删除）列表[x]元素，返回这个元素。 sorted()整理一个列表或元组等。 6.一些关键字： global：在函数中定义的变量默认是局部变量，局部变量覆盖同名全局变量。引入全局变量需要用global。 assert（断言）：判断后面跟着的表达式，若值为False则立刻终止程序并触发一个assert错误。 pass：用来占位。 yield：在函数中遇到yield后，会将所有局部变量保存，返回yield后面的对象，然后继续执行函数。yield主要是为了节省空间。 exec：将字符串当作python语句执行。总是返回None。 7.使用 字典名.items()来遍历字典。字典的get方法：get(key,default)用键找到对应的值，若没有则返回default，默认为None。 8.super方法：为了使子类调用父类方法可使用super方法。在python3中，格式为super().父类方法。在复杂的继承中，super调用的哪个方法可能比较复杂。 为了以一定的顺序快速寻找到指定方法，python使用了MRO（Method Resolution Order）方法解析顺序，涉及到C3算法。应该尽量避免多重继承。 9.str.strip([chars])方法：去除str两端的chars字符串，默认为去除空白符。 10. random库： >>> import random >>> random.choice(['apple', 'pear', 'banana'])'apple' >>> random.sample(range(100), 10) # sampling without replacement [30, 83, 16, 4, 8, 81, 41, 50, 18, 33] >>> random.random() # random float 0.17970987693706186 >>> random.randrange(6) # random integer chosen from range(6)4 11.后面可以不用看了

python中函数的多层嵌套与nonlocal
type: item
date: 2025-12-17T13:50:00+00:00
description: 步骤/目录： 无本文首发于个人博客https://lisper517.top/index.php/archives/4241/，转载请注明出处。本文的原文写作日期为2020年9月6日。本文的目的如标题所示。阅读《python基础教程第三版》第六章提到了函数及其作用域的嵌套。nonlocal为内部函数指定外部函数中的变量时使用。如果函数是三层嵌套会如何呢？我写了如下代码用于验证：def out(): x = 100 def middle(): x = 10 def mini(): nonlocal x print(x) return mini return middle out()()()结果输出了10。可见nonlocal有就近的原则。为了在mini中能够调用out中的x，我试着在mini中使用out.x或者声明global x，但都出现了错误。问题：如果出现了多层函数嵌套，在内层函数中应该如何指定使用哪一个作用域中的变量？