python生成器有几种写法,python生成器函数例子
大家好,小编来为大家解答以下问题,python生成器有几种写法,python生成器函数例子,今天让我们一起来看看吧!
本文部分参考:Python迭代器,生成器–精华中的精华 https://www.cnblogs.com/deeper/p/7565571.html
一 迭代器和可迭代对象
迭代器是访问集合元素的一种方式。火车头采集器AI伪原创。迭代器只能往前不会后退。迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素,仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件。
特点:a)访问者不需要关心迭代器内部的结构,仅需通过next()方法或不断去取下一个内容
b)不能随机访问集合中的某个值 ,只能从头到尾依次访问
c)访问到一半时不能往回退
d)便于循环比较大的数据集合,节省内存
e)也不能复制一个迭代器。如果要再次(或者同时)迭代同一个对象,只能去创建另一个迭代器对象。
enumerate()的返回值就是一个迭代器,我们以enumerate为例:
a = enumerate(['a','b'])for i in range(2): #迭代两次enumerate对象for x, y in a:print(x,y)print(''.center(50,'-'))
结果:
0 a
1 b
-----------------------分割线------------------------
-----------------------分割线------------------------
可以看到再次迭代enumerate对象时,没有返回值。
我们可以用linux的文件处理命令vim和cat来理解一下:
a) 读取很大的文件时,vim需要很久,cat是毫秒级;因为vim是一次性把文件全部加载到内存中读取;而cat是加载一行显示一行
b) vim读写文件时可以前进,后退,可以跳转到任意一行;而cat只能向下翻页,不能倒退,不能直接跳转到文件的某一页(因为读取的时候这个“某一页“可能还没有加载到内存中)。
正式进入python迭代器之前,我们先要区分两个容易混淆的概念:可迭代对象(Iterable)和迭代器(Iterator)。
1.1可迭代对象
定义:迭代器是一个对象,不是一个函数。只要它定义了可以返回一个迭代器的__iter__方法,或者定义了可以支持下标索引的__getitem__方法,那么它就是一个可迭代对象。
注意: 集合数据类型,如list、tuple、dict、set、str都是可迭代对象Iterable,却不是迭代器Iterator。
如何判断一个对象是可迭代对象呢?可以通过collections模块的Iterable类型判断:
from collections import Iterable
print(isinstance([], Iterable))
print(isinstance({}, Iterable))
print(isinstance('abc', Iterable))
print(isinstance({'name':'join','age':23},Iterable))
print(isinstance(set([2,3]),Iterable))
结果为:
True
True
True
True
True
再看:
from collections import Iterator
print(isinstance([], Iterator))
print(isinstance({}, Iterator))
print(isinstance('abc', Iterator))
print(isinstance({'name':'join','age':23},Iterator))
print(isinstance(set([2,3]),Iterator))
结果为:
False
False
False
False
False
1.2迭代器
定义:任何实现了__iter__()和__next__()(python2中实现next())方法的对象都是迭代器,__iter__返回迭代器自身,__next__返回容器中的下一个值。
这里我们来看一下迭代器和可迭代对象的使用方法。
问题:不适用for,while以及下表索引,怎么遍历一个list?
l1=[2,3,5]
iter_l1 = l1.__iter__()
# 或者iter(iter_l1)
# iter(iter_l1)是python的内置函数,
# l1.__iter__()调用的是l1对象的__iter__()方法。
# 下面的next()函数和__iter__()函数类似。
print(next(iter_l1)) # 或print(iter_l1.__next__()
print(next(iter_l1))
print(next(iter_l1))
print(next(iter_l1))
结果为:
2
3
5
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-126-eb58865cb644> in <module>4 print(next(iter_l1))5 print(next(iter_l1))
----> 6 print(next(iter_l1))
结论:思路就是,先得到当前对象(当前对象是可迭代对象)的迭代器,然后每次执行next(iter_l1)就可以得到当前对象的一个值。
修改一下:
l1=[2,3,5]
iter_l1 = l1.__iter__()
for i in iter_l1:print(i,end=',')
结果为:
2,3,5,
再次执行for语句如下:
for i in iter_l1:print(i,end=',')
此次返回结果为空,可以看到迭代器只能遍历一次对象,不能重复遍历。由于for语句可以自动处理StopIteration异常,所以这里没有报出StopIteration,而是没有任何结果。
看一个例子。我们想得到Fibonacci数列,思路是定义一个可迭代对象类Fib;然后在定义一个迭代器类FibIterator,使用方式是:
① 实例化一个可迭代对象: fib = Fib()
② 得到fib的一个迭代器: fib_iter = iter(fib)
③ 然后每次调用next(fib_iter)可得到fibonacci数列中的一个数。
class FibIterator():'''定义迭代器类'''def __init__(self,num,a,b,current):self.num = numself.a = aself.b = bself.current = currentdef __iter__(self):return selfdef __next__(self):if(self.num-1>=0):self.num = self.num-1self.current = self.aself.a = self.bself.b = self.b+self.current #以上两步赋值操作可省略中间变量直接写为self.a,self.b = self.b,self.a+self,b return self.currentelse: raise StopIterationclass Fib:'''定义可迭代对象所属类'''def __init__(self,num): #num表示该数列的长度self.a = 1self.b = 2self.current=self.aself.num = numdef __iter__(self):return FibIterator(self.num,self.a,self.b,self.current)fib = Fib(20)
fib_iter = iter(fib)
for i in range(20):print(next(fib_iter),end=',')
结果为:
1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,
这里定义的Fibonacci类的__init__函数有一个参数num,表示一共得到几个fibonacci数。
由于可迭代对象是实现了__iter__()方法的,迭代器对象是实现了__iter__()和__next__()方法的,能否只定义一个迭代器类呢?
试一下。
class Fib:def __init__(self,num):self.num = numself.a = 1self.b = 2self.current = self.adef __iter__(self):return selfdef __next__(self):if(self.num-1>=0):self.num = self.num-1self.current = self.aself.a = self.bself.b = self.b+self.current #以上两步赋值操作可省略中间变量直接写为self.a,self.b = self.b,self.a+self,b return self.currentelse: raise StopIterationfib = Fib(10)
for i in fib:print(i,end=',')
结果为:
1,2,3,5,8,13,21,34,55,89,
当我们再次执行for语句时,
for i in fib:print(i,end=',')
同上面的分析一样,结果为空。如果想再次得到fibonacci数列的前10个数,就必须重新实例化Fib对象。
结论:为什么不只保留Iterator的接口而还需要设计Iterable呢?
因为迭代器迭代一次以后就空了,那么如果list,dict也是一个迭代器,迭代一次就不能再继续被迭代了,这显然是反人类的;所以通过__iter__每次返回一个独立的迭代器,就可以保证不同的迭代过程不会互相影响。
另外,迭代器是惰性的,只有在需要返回下一个数据时它才会计算。所以,Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
下面的例子得到全体自然数(下面我们用生成器可以得到更简单的写法)。
class Natural:def __init__(self):passdef __iter__(self):return NaturalIterator()
class NaturalIterator:def __init__(self):self.beg=0self.current=self.begdef __iter__(self):return selfdef __next__(self):self.current += 1return self.current # 显示前20个自然数
n1=Natural()
n1_iter = iter(n1)
for i in range(20):print(next(n1_iter),end=',')
结果为:
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,
作业:使用迭代器和可迭代对象实现得到全体fibonacci数。
二 生成器
2.1 生成器的定义和使用
定义:生成器其实是一种特殊的迭代器,它不需要再像上面的类一样写__iter__()和__next__()方法了,只需要一个yiled关键字。
生成器一定是迭代器(反之不成立)。
Python有两种不同的方式提供生成器:
- 生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回结果。 yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行
- 生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象, 而不是一次构建一个结果列表
我们先用一个例子说明一下:
def generate_even():i=0while True:if i%2==0:yield ii += 1g=generate_even()
dir(g) # 可以看到里面有__iter__()方法和__next__()方法,所以生成器也是迭代器。for i in range(10):print(g.__next__(),end=',')
结果为:
0,2,4,6,8,10,12,14,16,18,
现在解释一下上面的代码:
我们知道,一个函数只能返回一次,即return以后,这次函数调用就结束了;
但是生成器函数可以暂停执行,并且通过yield返回一个中间值,当生成器对象的__next__()方法再次被调用的时候,生成器函数可以从上一次暂停的地方继续执行,直到下一次遇到yield语句(此时会返回yield后面的值,如果有的话)或者触发一个StopIteration。
了解协同程序:
a) 生成器的另外一个方面是协同程序的概念。协同程序是可以运行的独立函数调用,可以暂停或者挂起,并从程序离开的地方继续或者重新开始。
b) 可以在调用者和被调用的之间协同程序通信。
c) 在程序暂停时可以传参:举例来说,当协同程序暂停时,我们仍可以从其中获得一个中间的返回值,当调用回到程序中时,能够传入额外或者改变了的参数,但是仍然能够从我们上次离开的地方继续,并且所有状态完整。
生成器表达式类似于列表推导式,只是把[]换成(),这样就创建了一个生成器。
gen = (x for x in range(10))
下面我们用生成器来实现前面的fibonacci数列和全体自然数。
# 生成前n个fibonacci数
def fib(n):a, b = 0, 1count=0while True:if(count>n):breakcount += 1yield ba, b = b, a+bf = fib(20)
for item in f:print(item,end=',')
结果为:
1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,
def Natural():n=0while True:yield nn += 1
g_n1=Natural()
for i in range(20):print(next(g_n1),end=',')
结果为:
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
2.2 send方法
生成器函数最大的特点是可以接受外部传入的一个变量,并根据变量内容计算结果后返回。这是生成器函数最难理解的地方,也是最重要的地方,协程的实现就全靠它了。
看一个小猫吃鱼的例子:
def cat():print('我是一只hello kitty')while True:food = yieldif food == '鱼肉':yield '好开心'else:yield '不开心,人家要吃鱼肉啦'
中间有个赋值语句food = yield,可以通过send方法来传参数给food,试一下:
情况1)
miao = cat() #只是用于返回一个生成器对象,cat函数不会执行
print(''.center(50,'-'))
print(miao.send('鱼肉'))
结果:
Traceback (most recent call last):
--------------------------------------------------File "C:/Users//Desktop/Python/cnblogs/subModule.py", line 67, in <module>print(miao.send('鱼肉'))
TypeError: can't send non-None value to a just-started generator
看到了两个信息:
a)miao = cat() ,只是用于返回一个生成器对象,cat函数不会执行
b)can’t send non-None value to a just-started generator;不能给一个刚创建的生成器对象直接send值
改一下,情况2)
miao = cat()
miao.__next__()
print(miao.send('鱼肉'))
那么到底send()做了什么呢?send()的帮助文档写的很清楚,’’‘Resumes the generator and “sends” a value that becomes the result of the current yield-expression.’’’;可以看到send依次做了两件事:
a)回到生成器挂起的位置,继续执行b)并将send(arg)中的参数赋值给对应的变量,如果没有变量接收值,那么就只是回到生成器挂起的位置
但是,我认为send还做了第三件事:
c)兼顾__next__()作用,挂起程序并返回值,所以我们在print(miao.send(‘鱼肉’))时,才会看到’好开心’;其实__next__()等价于send(None)
所以当我们尝试这样做的时候:
def cat():print('我是一只hello kitty')while True:food = yieldif food == '鱼肉':yield '好开心'else:yield '不开心,人家要吃鱼肉啦'miao = cat()
print(miao.__next__())
print(miao.send('鱼肉'))
print(miao.send('骨头'))
print(miao.send('鸡肉'))
就会得到这个结果:
我是一只hello kitty
None
好开心
None
不开心,人家要吃鱼肉啦
我们按步骤分析一下:
a)执行到print(miao.next()),执行cat()函数,print了”我是一只hello kitty”,然后在food = yield挂起,并返回了None,打印None
b)接着执行print(miao.send(‘鱼肉’)),回到food = yield,并将’鱼肉’赋值给food,生成器函数恢复执行;直到运行到yield ‘好开心’,程序挂起,返回’好开心’,并print’好开心’
c)接着执行print(miao.send(‘骨头’)),回到yield ‘好开心’,这时没有变量接收参数’骨头’,生成器函数恢复执行;直到food = yield,程序挂起,返回None,并print None
d)接着执行print(miao.send(‘鸡肉’)),回到food = yield,并将’鸡肉’赋值给food,生成器函数恢复执行;直到运行到yield’不开心,人家要吃鱼肉啦’,程序挂起,返回’不开心,人家要吃鱼肉啦’,并print ‘不开心,人家要吃鱼肉啦’
大功告成,那我们优化一下代码:
def cat():msg = '我是一只hello kitty'while True:food = yield msgif food == '鱼肉':msg = '好开心'else:msg = '不开心,人家要吃鱼啦'miao = cat()
print(miao.__next__())
print(miao.send('鱼肉'))
print(miao.send('鸡肉'))
我们再看一个更实用的例子,一个计数器。
def counter(start_at = 0):count = start_atwhile True:val = yield countif val is not None:count = valelse:count += 1count = counter(5)
print(count.__next__())
print(count.send(0))
结果为5,0而不是5,6的原因:
①执行print(count.next()),程序运行到val = yield count(第一个yield语句)后挂起,然后返回yield后面的值,所以结果为5。
②执行print(count.send(0)),程序恢复到挂起点val = yield count,将send的参数0赋值给接受变量val,然后继续执行下面的语句,由于val=0,所以if val is not None条件为真,count = val,接着又来到yield语句(val = yield count),此时程序挂起,返回yield后面的值count=0。
综上:当执行next()方法时,程序会恢复到挂起点,依次执行yield语句下面的语句,最后再返回yield后面的值;而不是先返回yield后面的值,再执行yield后面的语句。
最后给出一张图说明Iterable,Iterator,Generator的关系:
补充几个小例子:
a)使用生成器创建一个range
def range(n):count = 0while count < n:yield countcount += 1
相关文章:
python生成器有几种写法,python生成器函数例子
大家好,小编来为大家解答以下问题,python生成器有几种写法,python生成器函数例子,今天让我们一起来看看吧! 本文部分参考:Python迭代器,生成器–精华中的精华 https://www.cnblogs.com/deeper/p…...
动态动画弹窗样式css
点击下载图片素材 html <div class"popWin"> </div> <div class"popPic"><div class"popWinBtn01">查看证书</div><div class"wintips01">恭喜您已完成训练营学习任务,荣誉证书已发放…...

数据生成 | MATLAB实现WGAN生成对抗网络数据生成
数据生成 | MATLAB实现WGAN生成对抗网络数据生成 目录 数据生成 | MATLAB实现WGAN生成对抗网络数据生成生成效果基本描述程序设计参考资料 生成效果 基本描述 1.WGAN生成对抗网络,数据生成,样本生成程序,MATLAB程序; 2.适用于MATL…...

PHP实现每日蛋白质摄入量计算器
1.laravel 路由 //每日蛋白质摄入计算器Route::get(api/protein/intake, FormulaControllerproteinIntakeCal); 2.代码 /*** 每日蛋白质摄入计算器*/public function proteinIntakeCal(){$number intval($this->request(number));$goalFactor array(0.8, 1.16, 0.8, 1.16,…...
vue elment 表格内表单校验代码
<p v-if"scope.row.id">{{ scope.row.bidderCode }}</p><el-form-itemclass"formitem"v-else:prop"bidderCode scope.row.id":rules"getValidationRules(投标人/供应商代码, scope.row.id)"><el-input v-model&…...

如何在Stream流中分组统计
上面是今天碰到需求,之前就做过类似的分组统计,这个相对来说比较简单,统计的也少,序号和总预约人数这两部分交给前端了,不需要由后端统计,后端统计一下预约日期和检查项目和预约人数就行; Overridepublic List<ItemStatisticsVo> statistics(ItemStatisticsModel itemSta…...

windows程序基础
一、windows程序基础 1. Windows程序的特点 1)用户界面统一、友好 2)支持多任务:允许用户同时运行多个应用程序(窗口) 3)独立于设备的图形操作 使用图形设备接口( GDI, Graphics Device Interface )屏蔽了不同硬件设备的差异&#…...

【LeetCode】买卖股票的最佳时机最多两次购买机会
买卖股票的最佳时机 题目描述算法分析程序代码 链接: 买卖股票的最佳时机 题目描述 算法分析 程序代码 class Solution { public:int maxProfit(vector<int>& prices) {int n prices.size();vector<vector<int>> f(n,vector<int>(3,-0x3f3f3f))…...

【C++ 记忆站】命名空间
文章目录 命名空间概念命名空间的定义1、正常的命名空间定义2、命名空间可以嵌套3、同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中 命名空间的使用1、加命名空间名称及作用域限定符2、使用using将命名空间中某个成员引入3、使用using namespac…...

《离散数学及其应用(原书第8版)》ISBN978-7-111-63687-8 第11章 11.1.3 树的性质 节 第664页的例9说明
《离散数学及其应用(原书第8版)》ISBN978-7-111-63687-8 第11章 11.1.3 树的性质 节 第664页的定理3的引申 定理3 带有i个内点的m叉树含有nmi1个顶点 见本人博文 内点定义不同的讨论 如果对于一个m叉正则树,即任意分支节点的儿子恰好有m个&am…...

【云原生】K8S存储卷:PV、PVC详解
目录 一、emptyDir存储卷二、hostPath存储卷三、nfs共享存储卷四、PVC 和 PV4.1 NFS使用PV和PVC4.2创建动态PV 一、emptyDir存储卷 容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题。首先,当容器崩溃时,ku…...

谈谈IP地址和子网掩码的概念及应用
个人主页:insist--个人主页 本文专栏:网络基础——带你走进网络世界 本专栏会持续更新网络基础知识,希望大家多多支持,让我们一起探索这个神奇而广阔的网络世界。 目录 一、IP地址的概念 二、IP地址的分类 1、A类 …...
vue2 如何监听数组的变化
在Vue 2中,底层是通过重写数组的原型方法来实现对数组变化的监听。具体来说,Vue 2使用了一个名为Observer的类来劫持数组的原型方法,使其在调用这些方法时能够触发相应的变化通知。 当Vue 2初始化一个响应式对象时,如果对象是一个…...

CSS中的transform属性有哪些值?并分别描述它们的作用。
聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ translate()⭐ rotate()⭐ scale()⭐ skew()⭐ matrix()⭐ scaleX() 和 scaleY()⭐ rotateX()、rotateY() 和 rotateZ()⭐ translateX() 和 translateY()⭐ skewX() 和 skewY()⭐ perspective()⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&…...

vue3跳转页面后 海康监控实例不销毁
第一个页面是这样的 跳转到新的页面 只有海康的监控没有消失 使用控制台审查元素也审查不到 解决方法:在vue3的销毁周期把海康的监控销毁掉 import { reactive, onDeactivated} from "vue"; const state reactive({oWebControl: null as any, //监控绑…...

Unity 射线检测
文章目录 1. 定义2. 重要类和方法2.1 Ray2.2 从屏幕发出射线:2.3 Raycast2.4 RaycastAll2.5 RaycastHit 碰撞信息2.6 layerMask 让射线检测只检测指定层级的对象 1. 定义 在Unity中,射线检测(Raycasting)是一种常用的技术&#x…...

微信支付报非法的密钥大小: Caused by: java.security.InvalidKeyException: Illegal key size
在Linux环境中出现 java.security.InvalidKeyException: Illegal key size 异常通常是由于Java默认的加密限制引起的。Java默认的加密强度限制了加密算法密钥的最大长度 方式一 1. 找到该目录 /usr/java/jdk1.8.0_121/jre/lib/security 2. 替换local_policy.jar 和 US_export_…...

React 调试开发插件 React devtools 的使用
可以在谷歌扩展应用商店里获取这个插件。如果不能访问谷歌应用商店,可以点此下载最新版 安装插件后,控制台出现 “Components” 跟 “Profiler” 菜单选项。 查看版本,步骤: 下面介绍 react devtools 的使用方式。 在 Component…...
linux 搜索命令
搜索命令 locate命令 搜索速度快,是按照数据库进行搜索的(数据库位置在/var/lib/mlocate/mlocate.db) locate abc.txt 这个数据库是在半夜通过cron执行updatedb建立的,有时候新创建的文件使用locate来搜索文件搜索不到,可能是因为文件的索引还…...

如何使用Spark/Flink等分布式计算引擎做网络入侵检测
如何使用Spark/Flink等分布式计算引擎做网络入侵检测 引言16 Distributed Abnormal Behavior Detection Approach Based on Deep Belief Network and Ensemble SVM Using Spark17 Spark configurations to optimize decision tree classification on UNSW-NB1518 A dynamic spa…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...

Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

基于Java+VUE+MariaDB实现(Web)仿小米商城
仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...