渗透测试之Python基础与进阶 – 作者:MoLing

浏览一些招聘信息,发现很多公司要求熟悉以下两种或以上的语言:PHP,JavaScript,Python,Java,Ruby.今天来总结一下我学习python的一些小内容,以及分享一下关于Python、Java等编程语言的学习方法,希望你也能像我一样,学语言的时候眼里放着光哟。

呐,本文纯属小菜鸟的学习总结,如有错误,请指正。小丫头儿在此谢过啦~~~

0x00 Python学习

1)学习方法

项目式学习         ==》通过一些练习来具象化Python的语法和概念,这样能够学以致用

编程思维的训练  ==》学习语言最好的书籍就是他的官方文档(可以在官网上下载查看,文末附链接)

学会利用help      ==》在使用某些库的时候,可以通过IDLE通过dir,help来查询使用方法

2)Python的优缺点

优点

简单易学,上手快

有丰富的库,便于调用

可扩展、可嵌入(嵌入C语言来优化)

免费开源、可移植

解释性语言(不需要事先编译)

面向对象、高层

缺点

运行效率略低

多线程支持欠佳

商业支持不足

代码不能加密(既是缺点又是优点)

无类型

3)Python的注释

单行注释      #

多行注释      “”” 注释内容 “””

缩进              tab

注释快捷键   ctrl+/  (部分其他语言也适用)

4)内置函数(https://www.runoob.com/python3/python3-built-in-functions.html)

 

0x01 Python变量

 1. 变量阐述

计算机的核心是CPU,程序运行在内存(内部存储器),变量在内存就像一个仓库,存储着各种各样数据的仓库,我们通过变量可以找到相应数据。

我们把变量比作一个盒子,里面存放着各种各样的数据(可存可改可读可写)。例如: a=10我们可以通过id(a)来查询a这个变量现在所在的位置。由于一个变量一次只能对应一个数值;而一个数值可以同时赋值给多个变量,所有我们以‘标签理论’来解释变量赋值这个问题(变量就像给数值贴标签)。

Python一切皆对象,首先我们来看:

First:
>>> list1=[‘a’,’b’,’c’]
>>> list2=list1
>>> list2 [‘a’, ‘b’, ‘c’]
>>> list1.append(‘d’)
>>> list2 [‘a’, ‘b’, ‘c’, ‘d’]
>>> id(list1) 60660272
>>> id(list2) 60660272

 

通过以上代码我们可以知道,变量 list1和 list2所对应的数值内随添加了 ‘d ’这个对象,但所对应的列表对象本身是没有改变的,所以我们列表[‘a’,’b’,’c’]所对应的标签仍然是变量 list1 和 list2。

图片[1]-渗透测试之Python基础与进阶 – 作者:MoLing-安全小百科

 

Second:
>>> num1=1
>>> id(num1) 2064409776
>>> num2=num1
>>> id(num2) 2064409776
>>> num1=2
>>> num2 1
>>> id(num1) 2064409792 ===》边界位256(最后一个固定id的数,257的id随机)
        通过以上代码,我们可以发现,num1=1 && num2=num1 时,num1和num2都被贴到了 1 上,但在num1的值改变时,num2未改变num1和num2对应的id和值都不同了。见下图:
图片[2]-渗透测试之Python基础与进阶 – 作者:MoLing-安全小百科

以上两个项目是不同的:
        ①是list1这个大的对象里面包含很多不同类型的对象,所以再追加进其他对象后,不影响整个数组对象,list1和list2的id是不变的,二者内容也是相同的
        ②第二个项目的对象是1,但后面修改了num1的值,也就修改了其对象,但num2的值仍然是1,不受num1影响,二者内容不同,且num1的id改变了

2. 命名规则(Python的关键字,不可作为命名)==》关键字=保留字

>>> import keyword
>>> keyword.kwlist [‘False’, ‘None’, ‘True’, ‘and’, ‘as’, ‘assert’, ‘break’, ‘class’, ‘continue’, ‘def’, ‘del’, ‘elif’, ‘else’, ‘except’, ‘finally’, ‘for’, ‘from’, ‘global’, ‘if’, ‘import’, ‘in’, ‘is’, ‘lambda’, ‘nonlocal’, ‘not’, ‘or’, ‘pass’, ‘raise’, ‘return’, ‘try’, ‘while’, ‘with’, ‘yield’]
命名规则:小写_下划线_小写(除了类用大写开头)

图片[3]-渗透测试之Python基础与进阶 – 作者:MoLing-安全小百科3. 运算符优先级:(运算符部分和其他语言类似)

运算符
描述
**
指数 (最高优先级)
~ + –
按位翻转, 一元加号和减号 (最后两个的方法名为 +@ 和 -@)
* / % //
乘,除,求余数和取整除
+ –
加法减法
>> <<
右移,左移运算符
&
位 ‘AND’
^ |
位运算符
<= < > >=
比较运算符
== !=
等于运算符
= %= /= //= -= += *= **=
赋值运算符
is is not
身份运算符
in not in
成员运算符
not and or
逻辑运算符

0x02 Python流程控制

1. 顺序结构

        即程序按照其运行顺序和运算符优先级的顺序进行执行

2. 分支结构

        即 if ,有条件为真和条件为假两种运算方式。

3. 循环结构

        即 for 和 while 。for循环可以遍历任何序列的函数;while是当满足条件就可以一直执行。

4.其他语句

  • break : 用于结束整个循环(类似于这个循环崩坏,结束循环)
  • continue :结束本次循环(会继续运行下一次,相当于跳过这次循环)
  • pass : 相当于占位符,什么都不执行(在待修改的程序框架中,可先用pass占位符占位,以免程序出错)
  • else : 一般和 if 一起使用,选取满足条件时锁执行的代码块

0x03 Python字符串

1. 字符串定义 : 

        字符串是一种文本数据类型  ==》  单引号,双引号,三引号(在赋值时,三引号表示字符串)

转义字符
描述
\(在行尾时)
续行符
\\
反斜杠符号
\’
单引号
\”
双引号
\a
响铃
\b
退格(Backspace)
\000
\n
换行
\v
纵向制表符
\t
横向制表符
\r
回车
\f
换页

2. 字符串运算符:

操作符
描述
实例
+
字符串连接
a + b 输出结果: HelloPython
*
重复输出字符串
a*2 输出结果:HelloHello
[]
通过索引获取字符串中字符
a[1] 输出结果 e
[ : ]
截取字符串中的一部分,遵循左闭右开原则,str[0:2] 是不包含第 3 个字符的。
a[1:4] 输出结果 ell
in
成员运算符 – 如果字符串中包含给定的字符返回 True
‘H’ in a 输出结果 True
not in
成员运算符 – 如果字符串中不包含给定的字符返回 True
‘M’ not in a 输出结果 True
r/R
原始字符串 – 原始字符串:所有的字符串都是直接按照字面的意思来使用,没有转义特殊或不能打印的字符。 原始字符串除在字符串的第一个引号前加上字母 r(可以大小写)以外,与普通字符串有着几乎完全相同的语法。
print( r’\n’ )
print( R’\n’ )
%
格式字符串
 

 

3. 字符串运算符的使用

>>> print(“我好喜欢你%s”%’佳儿’) ==》%s表示输出的是字符串
我好喜欢你佳儿
>>> print(‘你体重是%10.3f’%52.1314) ==》%10.3f 表示输出数值范围为小数点前十位后三位
你体重是 52.131
>>> print(r’I\nlove you’) ==》r’I\nlove you’ 中的 r 表示输出的是原始字符串
I\nlove you

 

4. 字符串的切片

切片:(正常切片不能获取到end位置的值)
a[start:stop[:step]] ===> 左闭右开(闭包)
>>> a[‘abcds’]
>>> a[::-1]
‘sdcba’
>>> a[::1]
‘abcds’

5. 字符串内置函数

①find() 描述
        find() 方法检测字符串中是否包含子字符串 str ,如果指定 beg(开始) 和 end(结束) 范围,则检查是否包含在指定范围内,如果指定范围内如果包含指定索引值,返回的是索引值在字符串中的起始位置。如果不包含索引值,返回-1。
语法
find()方法语法:
str.find(str, beg=0, end=len(string))
参数
  • str — 指定检索的字符串
  • beg — 开始索引,默认为0。
  • end — 结束索引,默认为字符串的长度。
返回值
如果包含子字符串返回开始的索引值,否则返回-1。
str.find(str,[beg[,end]]) ===> beg指的是索引,默认为0;end是结束索引,默认为字符串长度
str.find(‘loveyou’) ===> ‘loveyou’.find(‘l’) ===>0
>>> ‘abcdefg’.find(‘a’,2,5) -1
>>> ‘abcdefg’.find(‘c’,2,5) 2
重载:使用不同参数得到不同结果
>>> ‘abcdefcccg’.find(‘c’,2,5)
2
 
②count() 描述
       count() 方法用于统计字符串里某个字符出现的次数。可选参数为在字符串搜索的开始与结束位置。
语法
count()方法语法:
str.count(sub, start= 0,end=len(string))
参数
  • sub — 搜索的子字符串
  • start — 字符串开始搜索的位置。默认为第一个字符,第一个字符索引值为0。
  • end — 字符串中结束搜索的位置。字符中第一个字符的索引为 0。默认为字符串的最后一个位置。
返回值
该方法返回子字符串在字符串中出现的次数。
str.count(str,[beg[,end]])
>>> ‘abcdesssscccfg’.count(‘c’,2,15)
4
 
③replace()描述
        replace() 方法把字符串中的 old(旧字符串) 替换成 new(新字符串),如果指定第三个参数max,则替换不超过 max 次。
语法
replace()方法语法:
str.replace(old, new[, max])
参数
  • old — 将被替换的子字符串。
  • new — 新字符串,用于替换old子字符串。
  • max — 可选字符串, 替换不超过 max 次
返回值
返回字符串中的 old(旧字符串) 替换成 new(新字符串)后生成的新字符串,如果指定第三个参数max,则替换不超过 max 次。
str.replace(str,str[,max])
>>> ‘abcdesssscccfg’.replace(‘ccc’,’g’)
‘abcdessssgfg’
 
④split()描述
        split() 通过指定分隔符对字符串进行切片,若第二个参数 num 有指定值,则分割为 num+1 个子字符串。
语法
split() 方法语法:
str.split(str=””, num=string.count(str))
参数
  • str — 分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。
  • num — 分割次数。默认为 -1, 即分隔所有。
返回值
返回分割后的字符串列表。
str.aplit(str=””,num=string.count(str)) ==> 字符串切片变成列表
>>> ‘abcdesssscccfg’.split(‘c’,5)
[‘ab’, ‘dessss’, ”, ”, ‘fg’]
 
⑤strip() 描述
strip() 方法用于移除字符串头尾指定的字符(默认为空格)或字符序列。
注意:该方法只能删除开头或是结尾的字符,不能删除中间部分的字符。
语法
strip()方法语法:
str.strip([chars]);
参数
  • chars — 移除字符串头尾指定的字符序列。
返回值
返回移除字符串头尾指定的字符序列生成的新字符串。
str.strip([chars]) ==> 清除左右的字符
str.lstrip([chars])
str.rstrip([chars])
>>> ‘ abcdes ssscccf g ‘.strip()
‘abcdes ssscccf g’

6. 字符串运算符

操作符
描述
实例
+
字符串连接
a + b 输出结果: HelloPython
*
重复输出字符串
a*2 输出结果:HelloHello
[]
通过索引获取字符串中字符
a[1] 输出结果 e
[ : ]
截取字符串中的一部分,遵循左闭右开原则,str[0:2] 是不包含第 3 个字符的。
a[1:4] 输出结果 ell
in
成员运算符 – 如果字符串中包含给定的字符返回 True
‘H’ in a 输出结果 True
not in
成员运算符 – 如果字符串中不包含给定的字符返回 True
‘M’ not in a 输出结果 True
r/R
原始字符串 – 原始字符串:所有的字符串都是直接按照字面的意思来使用,没有转义特殊或不能打印的字符。 原始字符串除在字符串的第一个引号前加上字母 r(可以大小写)以外,与普通字符串有着几乎完全相同的语法。
print( r’\n’ )
print( R’\n’ )
%
格式字符串
 

 

0x04 Python四种基本类型

1. 数据类型:

        数据结构:相互之间存在一种或多种特定关系的数据或元素的结合。数据按照某种特定的结构存储。
  • 列表:有序可变(增删改查) ===》 list[] 从0开始编号

        增加方法有:insert 任意位置插入;append 在尾部追加;extend 列表拼接(a.extend([5,6,8,9]))

        删除方法有:pop 将列表中的数据弹出并删除;remove 将列表中指定的数据删除,不显示出来

        修改方法有:index 通过索引来进行修改  

        查询方法有:in 和 not in

        排序方法有:sort方法是列表的元素按照特定的顺序排列;reverse方法是将列表逆置

  • 元组:有序不可变(查)   ===》 tuple()

 

Python 表达式
结果
描述
len((1, 2, 3))
3
计算元素个数
(1, 2, 3) + (4, 5, 6)
(1, 2, 3, 4, 5, 6)
连接
(‘Hi!’,) * 4
(‘Hi!’, ‘Hi!’, ‘Hi!’, ‘Hi!’)
复制
3 in (1, 2, 3)
True
元素是否存在
for x in (1, 2, 3): print (x,)
1 2 3
迭代
  • 集   合:无序唯一可变          ===》set{}  交集,补集 ,下标从零开始
        在set中set.pop()内存储的是字符串的时候,随机弹出删除,存储的是元组或者列表,先排序在从左到右依次删除
(1, 2, 3, 4, 5, 6)
>>> b.count(1)
1
>>> b.index(2)
1
  • 字典:无序可变 ===》 dict(key,value)    {‘ ’:‘ ’;‘ ’:‘ ’}
        键值对 ==》get一个不存在的,返回空;直接输出一个不存在的值,报错
        info[‘id’] 查id ===> 可用于修改值
        删除元素:pop(根据key值删除字典重点的元素);clear(清空字典中的数据,字典还在,元素没了)
        keys(输出所有key)   /   values(输出所有value)   /    items(输出所有键值对)
>>> c={‘a’,’b’,’c’,’d’,’e’}
>>> c.add(‘f’)
>>> c
{‘e’, ‘c’, ‘d’, ‘a’, ‘f’, ‘b’}
>>> c.pop() ‘e’
{‘d’, ‘a’, ‘love’, ‘f’, ‘b’}
>>> c.discard(1)
>>> c
{‘a’, ‘love’, ‘f’, ‘b’}
>>> d={‘1′,’2’}
>>> c.union(d)
{‘love’, ‘f’, ‘1’, ‘2’, ‘b’, ‘a’}
>>> c.difference(d)
{‘f’, ‘b’, ‘a’, ‘love’}

2. Python字典包含了以下内置函数:

序号
函数及描述
实例
1
len(dict)
计算字典元素个数,即键的总数。
>>> dict = {‘Name’: ‘Runoob’, ‘Age’: 7, ‘Class’: ‘First’}
>>> len(dict)
3
2
str(dict)
输出字典,以可打印的字符串表示。
>>> dict = {‘Name’: ‘Runoob’, ‘Age’: 7, ‘Class’: ‘First’}
>>> str(dict)
“{‘Name’: ‘Runoob’, ‘Class’: ‘First’, ‘Age’: 7}”
3
type(variable)
返回输入的变量类型,如果变量是字典就返回字典类型。
>>> dict = {‘Name’: ‘Runoob’, ‘Age’: 7, ‘Class’: ‘First’}
>>> type(dict)
<class ‘dict’>

0x05 Python函数

1. 函数:

        函数是组织好的、可重复使用的,用于解决代码重复性问题。(定义函数关键字是def)

def print_info():
函数体
fn() #调用函数

 

2. 不定长参数

        有时可能需要一个函数能处理比声明时更多的参数,这些参数叫不定长参数,声明时不会命名
一个星号表示列表型的;两个星号表示键值对的
def functionname([formal_args,]*args,**kwargs):
“函数——文档字符串”
function_suite
return[expression] #函数的返回值:return
 
def test(a, b, *args):
print(a)
print(b)
print(args)
test(1,2,4,5,6) .

 

3. 根据函数的参数和返回值,函数可以分为四种类型:

        ①无参数,无返回值的函数
        ②无参数,有返回值的函数
        ③有参数,无返回值的函数
        ④有参数,有返回值的函数

4.变量的作用域:

  • 为避免变量名称发送冲突,所有python引入了命名空间的概念。
  • 命名空间指的是名称到对象的映射,类似于字典,键名是变量的名称,值是变量的值
  • 内部要改变全局变量,要global声明
  • 闭包:函数内部包含一个函数,函数用函数的数据==》闭包函数–nonlocal(用外面的数据)
#nonlocal闭包函数
def outer():
num = 10
def inner():
nonlocal num # nonlocal关键字声明
num = 100 print(num)
inner()
print(num)
outer()
  • 递归函数:函数自己调用自己
  • 匿名函数:函数功能简短就可以使用匿名函数(可能只是用一次就不用了)   
          匿名函数就是没有名称的函数,也就是不再使用def语句定义的函数。如果要声明匿名函数,则需要使用lambda关键字 ===》 lambda[arg1[,arg2,…,argn]]:expressing

0x06 简单介绍Python的算法

1. 算法

        是指解题方案(一种问题的解决方案)准确而完整的描述,是一系列解决问题的清晰指令
        range(4) ===> 0,1,2,3

2. 选择排序

a = [5,7,8,3,1]
for j in range(len(a)-1):
for i in range(j,len(a)-1):
if a[j] > a[i+1]:
a[j],a[i+1] = a[i+1],a[j]
print(a)

3. 冒泡排序(省时间优化)

b = [5,7,8,3,1]
for j in range(len(b)-1):
swap = False
for i in range(len(b)-j-1):
if b[i] > b[i+1]:
b[i],b[i+1] = b[i+1],b[i]
swap = True
if swap == False:
break
print(b)

4.时间复杂度和空间复杂度(判断一个算法是否优秀的标准)

图片[4]-渗透测试之Python基础与进阶 – 作者:MoLing-安全小百科
 

0x07 Flask制作一个Web应用

1. Flask框架介绍:(微框架)

@函数修饰符:在不修改原代码的同时,扩展函数能力
@app.route(‘/’) 函数修饰符可使下面的函数内容输出到网页
pip install flask -i https://mirrors.aliyun.com/pypi/simple
#flask_test
from flask import Flask
app = Flask(__name__)

 

@app.route(‘/’) #函数修饰符
def first_flask():
      return “hello”
app.run()

 

2. 应用案例

需要建一个符合Flask框架要求的文件夹子,里面包含:static文件夹(存储静态文件);tenplates文件夹(存放模板文件)

#flask_test

from flask import Flask,render_template #渲染模板

app = Flask(__name__)

@app.route(‘/hello’)

def first_flask():

return “hello”

@app.route(‘/enter’)

def enter_page():

return render_template(‘enter.html’,the_title=’主页’,)

#return输出内容当三对引号时可插入多行,可换行

app.run(debug=True)

3. Jinja介绍

Jinja是一种以Django模板为模型的,现代且设计友好的Python模板语言。借助可选的沙盒模板执行环境,它可以快速,广泛地使用并且安全:
<title>{% block title %}{% endblock %}</title>
<ul> {% for user in users %}
    <li><a href=”{{ user.url }}”>{{ user.username }}</a></li>
{% endfor %}
</ul>
特征:
  • 沙盒执行
  • 强大的HTML自动转义系统,可防止XSS
  • 模板继承
  • 及时编译为最佳python代码
  • 可选的提前模板编译
  • 易于调试。例外的行号直接指向模板中的正确行。
  • 可配置语法

4. 完整项目    python部分

#flask_test

import area as area

from flask import Flask,render_template,request #渲染模板

import math

import re

app = Flask(__name__)

@app.route(‘/hello’)

def first_flask():

return “hello”

@app.route(‘/enter’)

def enter_page():

return render_template(‘enter.html’, the_title=’主页’,)

@app.route(‘/area’,methods=[‘POST’])

def area_page():

radius = request.form[‘radius’]

if radius == ” or radius.isspace==None:

radius = 0

if re.match(‘([0-9]|\.){‘+str(len(radius))+’}’,radius) == None:

radius = 0

area = round(math.pi*float(radius)**2,3)

return render_template(‘area.html’, the_radius=radius, the_area=area,)

app.run(debug=True)

 

0x08 存储数据

1. 文件存储

      文件==》打开(open),写(read/write),关闭(close)==>凡是打开后都要关闭
f=open(‘1.txt’,’r’,encoding=’utf-8′)
print(f.read())
f.close()
      优化后:变得更简洁优雅,可自动close
with open(‘1.txt’,’r’,encoding=’utf-8′) as f:
print(f.read())
      读写方式:
Character Meaning
——— —————————————————————
‘r’ open for reading (default)
‘w’ open for writing, truncating the file first
‘x’ create a new file and open it for writing
‘a’ open for writing, appending to the end of the file if it exists
‘b’ binary mode
‘t’ text mode (default)
‘+’ open a disk file for updating (reading and writing)

 

2. 数据库存储

  •  数据库:更好的存储、管理数据
  • 关系型数据库:采用了关系模型来组织数据的数据库,其以行和列的形式存储数据,以便于用户理解,关系型数据库这一系列的行和列被称为表,一组表组成了数据库

3. 文件读写的函数

①tell()概述
tell() 方法返回文件的当前位置,即文件指针当前位置。
语法
tell() 方法语法如下:
fileObject.tell()
返回值
返回文件的当前位置。
 
②seek()概述
seek() 方法用于移动文件读取指针到指定位置。
语法
seek() 方法语法如下:
fileObject.seek(offset[, whence])
参数
  • offset — 开始的偏移量,也就是代表需要移动偏移的字节数,如果是负数表示从倒数第几位开始。
  • whence:可选,默认值为 0。给 offset 定义一个参数,表示要从哪个位置开始偏移;0 代表从文件开头开始算起,1 代表从当前位置开始算起,2 代表从文件末尾算起。
返回值
如果操作成功,则返回新的文件位置,如果操作失败,则函数返回 -1。
 

 4. 存储内容:

    ①表单信息: request.form
    ②服务器地址: request.remote_ addr
    ③客户端信息: request.user _agent
    ④返回结果:运算结果

5. 案例代码:

#flask_test 案例一
import area as area
from flask import Flask,render_template,request   #渲染模板
import math
import re

app = Flask(__name__)
#def do_area(redius):
#    return math.pi*float(redius)**2

@app.route(‘/hello’)
def first_flask():
    return “hello”

@app.route(‘/enter’)
def enter_page():
    return render_template(‘enter.html’,
                           the_title=’主页’,)

@app.route(‘/area’,methods=[‘POST’])
def area_page():
    radius = request.form[‘radius’]
    if radius == ” or radius.isspace == None:
        radius = 0
    if re.match(‘([0-9]|\.){‘+str(len(radius))+’}’,radius) == None:
        radius = 0
    area = round(math.pi*float(radius)**2,3)
    with open(‘log.txt’,’a’) as f:
        f.write(str(request.form)+’,’+request.remote_addr+’,’+str(request.user_agent)+’,’+str(area))
        #print(request.form,request.remote_addr,sep=’|’,file=f)
    return render_template(‘area.html’,
                           the_radius=radius,
                           the_area=area,)

@app.route(‘/file_out’)
def file_out_page():
    log = []
    with open(‘log.txt’,’r’,encoding=’utf-8′) as out:
        log = out.readlines()
        return render_template(‘file_out.html’)
        return  str(log)

if __name__==’__main__’:
    app.run(debug=True)

 

案例二:html

{% extends “base.html” %}
{% block body %}
<table border=””>
    <tr>
    <th>str(request.form)</th>
    <th>request.remote_addr</th>
    <th>str(request.user_agent)</th>
    <th>str(area))</th>
    </tr>
    {% for x in file1 %}
    <tr>
        {% for i in x %}
        <td>{{ i }}

        </td>
        {% endfor %}
    </tr>{% endfor %}
</table>

{% endblock %}

 

案例二:python

#flask_test
import area as area
from flask import Flask,render_template,request   #渲染模板
import math
import re

app = Flask(__name__)
#def do_area(redius):
#    return math.pi*float(redius)**2

@app.route(‘/hello’)
def first_flask():
    return “hello”

@app.route(‘/enter’)
def enter_page():
    return render_template(‘enter.html’,
                           the_title=’主页’,)

@app.route(‘/area’,methods=[‘POST’])
def area_page():
    radius = request.form[‘radius’]
    if radius == ” or radius.isspace == None:
        radius = 0
    if re.match(‘([0-9]|\.){‘+str(len(radius))+’}’,radius) == None:
        radius = 0
    area = round(math.pi*float(radius)**2,3)
    with open(‘log.txt’,’a’) as f:
        f.write(str(request.form)+’~’+request.remote_addr+’~’+str(request.user_agent)+’~’+str(area))
        #print(request.form,request.remote_addr,sep=’|’,file=f)
    return render_template(‘area.html’,
                           the_radius=radius,
                           the_area=area,)

@app.route(‘/file_out’)
def file_out_page():
    log = []
    with open(‘log.txt’,’r’,encoding=’utf-8′) as out:
        log = out.readlines()
        file = []
        for i in log:
            file.append(i.split(‘~’))
        ”’return render_template(‘file1_out.html’,
                               the_from=str(request.form),
                               the_addr=request.remote_addr,
                               the_ua=str(request.user_agent),
                               the_area=str(area))”’
        return render_template(‘file1_out.html’,
                               file1=file)
        #print(log)
        #return  str(log)

if __name__==’__main__’:
    app.run(debug=True)

0x09 数据库管理数据

1. 使用Python内置的数据库SOLite:

     ①SQLite本身是C写, 所以体积小巧,占用资源低
     ②SQLite本身是C写,所以处理速度非常快
     ③SQLite已经发布SQLite 3版本
     ④SQLite3支持Windows/Linwx/Unix等主流操作系统
     ⑤Python 2.5.x以上版本默认内置SQLite3,无需单独安装和配置,直接使用

2.SQLite介绍

     SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库,这意味着与其他数据库不一样,您不需要在系统中配置。

就像其他数据库,SQLite 引擎不是一个独立的进程,可以按应用程序需求进行静态或动态连接。SQLite 直接访问其存储文件。
使用:
      $sqlite3 DatabaseName.db : 创建数据库
      sqlite> .databases : 显示数据库
      .help: 获取命令清单
      .show:查看sqlite命令提示符的默认设置
      .tables:查看表名
      .schema sqlite_ master: 查看表概要
      .quit: 退出
存储类
描述
NULL
值是一个 NULL 值。
INTEGER
值是一个带符号的整数,根据值的大小存储在 1、2、3、4、6 或 8 字节中。
REAL
值是一个浮点值,存储为 8 字节的 IEEE 浮点数字。
TEXT
值是一个文本字符串,使用数据库编码(UTF-8、UTF-16BE 或 UTF-16LE)存储。
BLOB
值是一个 blob 数据,完全根据它的输入存储。
      SQLite 的存储类稍微比数据类型更普遍。INTEGER 存储类,例如,包含 6 种不同的不同长度的整数数据类型。

3. MySQL

当遇到问题时==》? create table 查询创建数据表的用法
                              ? contents 查看数据类型
      对比之下,插入多行时,用VALUE比较快根据所得出的结论,应该在插入单行的时候使用VALUES,在插入多行的时候使用VALUE
修改表中指定字段==》alter table log change column browser_string brower_string varchar(200);

#flask_test
import area as area
from flask import Flask,render_template,request   #渲染模板
import math
import re
import pymysql
from DBcm import UseDatabase

app = Flask(__name__)

@app.route(‘/hello’)
def first_flask():
    return “hello”

@app.route(‘/enter’)
def enter_page():
    return render_template(‘enter.html’,
                           the_title=’主页’,)

@app.route(‘/area’,methods=[‘POST’])
def area_page():
    radius = request.form[‘radius’]
    if radius == ” or radius.isspace == None:
        radius = 0
    if re.match(‘([0-9]|\.){‘+str(len(radius))+’}’,radius) == None:
        radius = 0
    area = round(math.pi*float(radius)**2,3)
    ”’
    mysql学习
    ”’
    #连接数据库
    conn = pymysql.connect(‘127.0.0.1’, ‘root’, ‘root’, ‘test’)
    cursor = conn.cursor()
    # 数据库文件读写
    sql = ”’insert into mysql1(radius,browser_string,area) values(%s,%s,%s)”’
    cursor.execute(sql, (float(radius), str(request.user_agent), str(area)))
    conn.commit()
    #关闭连接
    cursor.close()
    conn.close()

    return render_template(‘area.html’,
                                the_radius=radius,
                                the_area=area, )

@app.route(‘/file_out’)
def file_out_page():
    # 连接数据库
    conn = pymysql.connect(‘127.0.0.1’, ‘root’, ‘root’, ‘test’)
    cursor = conn.cursor()
    # 数据库文件读写
    sql=”””select radius,browser_string,area from mysql1″””
    cursor.execute(sql)
    result = cursor.fetchall()
    conn.commit()
    # 关闭连接
    cursor.close()
    conn.close()
    return render_template(‘file1_out.html’,
                           file1=result)

if __name__==’__main__’:
    app.run(debug=True)

0x0A 面向对象

1.面向对象:(封装,继承,多态,重载)对象=属性(静态)+行为(动态=》方法,函数)

      在现实世界中存在各种不同形态的事物,这些事物之间存在着各种各样的联系。在程序中使用对象来映射现实中的事物,使用对象间的关系来描述事物之间的联系,这种思想就是面向对象。

2.类的定义:class类名,类的属性,类的方法

      类是由3部分组成的:
    ●类的名称:类名,首字母必须大写,比如Person。
    ●类的属性:一组数据,比如性别。
    ●类的方法:允许进行操作的方法,比如说话。

”’

”’
class Man:
    weight = 120        #类的属性
    def __init__(self,n,a,h):     #可以理解为构造函数
        self.name = n
        self.age = a
        self.height = h
    def hello(self):
        print(“你好,我是***”+self.name)

class Boy(Man):
    def __init__(self,n,a,h):     #可以理解为构造函数,初始化
        self.name = n
        self.age = a
        self.height = h
    def hello(self):
        print(“你好,我是—“+self.name)

    @staticmethod   #静态方法:不能访问对象的东西,类方法访问不需要实例化
    def eat():
        print(‘恰饭!!!’)

    @property       #方法属性  ==>   把方法属性化,调用不用加括号
    def a(self):
        return self.age
        #print(‘我的年龄:’,self.age)

lai = Man(‘lai’,22,170)     #多态
bob = Boy(‘BOB’,18,120)
print(bob.a)
Boy.eat()
Man.hello(lai)
Boy.hello(lai)

#bob.hello()              #Boy.hello(bob)
#print(bob.age)
#Boy.eat()

3. 构造方法:

    ●构造方法指的是_ init_ 方法。==>初始化
    ●当创建类的实例的时候,系统会自动调用构造方法,从而实现对类进行初始化的操作。
析构方法:
    ●当删除一个对象来释放类所占用资源的时候,Python解释器默认会调用另外一个方法,这个方法就是___del__ ( )方法。
    ●__del__ 方法被称为析构方法。
    C++需要手动析构;Python,Java会虚拟机自动销毁

 4. self的使用:

    ●在方法的列表中,第1个参数永远都是self。
    ●self的字面意思是自己, 我们可以把它当做C+ +里面的this指针理解,表示的是对象自身。
    ●当某个对象调用方法的时候,Python解释器 会把这个对象作为第1个参数传给self,开发者只需要传递后面的参数就可以了。

5. 运算符重载

    运算符重载是通过实现特定的方法使类的实例对象支持Python的各种内置操作。例如: +运算符是类里提供的__add__ 这个函数,当调用+实现加法运算的时候,实际上是调用了__add__ 方法。

#重载是根据传入的参数个数的不同,会执行不同的函数
class Vector:
   def __init__(self, a, b):
      self.a = a
      self.b = b
 
   def __str__(self):
      return ‘Vector (%d, %d)’ % (self.a, self.b)
   
   def __add__(self,other):
      return Vector(self.a + other.a, self.b + other.b)
 
v1 = Vector(2,10)
v2 = Vector(5,-2)
print (v1 + v2)

#重写是,子类继承父类后,子类对父类部分方法和函数进行重新书写
class Parent:        # 定义父类
   def myMethod(self):
      print (‘调用父类方法’)
 
class Child(Parent): # 定义子类
   def myMethod(self):
      print (‘调用子类方法’)
 
c = Child()          # 子类实例
c.myMethod()         # 子类调用重写方法
super(Child,c).myMethod() #用子类对象调用父类已被覆盖的方法

6.索引和分片重载

跟索引相关的重载方法包括如下3个:
    ●__getitem__ : 索引、分片;
    ●__setitem__ :索引赋值;
    ●__delitem__ :索引和分片删除。
      ①__getitem__方法
          在对实例对象执行索引、分片或者for迭代操作时,会自动调用__getitem__方法。通过此方法实现求值,对于序列类型,接受的键应为整数和切片对象。
#定义索引、分片运算符重载方法
                def __getitem__(self, index):
                return self.data[index]
 
      ②__setitem__方法
          通过赋值语句给索引或者分片赋值时,调用__setitem__方法实现对序列对象的修改。
             def __setitem__ (self, index, value):
             self.data[index] = value
 
     ③__delitem__方法
           这个方法在对对象的组成部分使用__del__语句的时候被调用,应删除与key相关联的值。同样,仅当对象可变的时候,才需要实现这个方法。

0x0B 上下文管理协议

1. 定义:一个包装任意代码的对象,适合“建立、处理、清理”模式的代码

with open( ‘test.txt’,’w’)as f:
f.write( ‘我想做个好人! ‘
作用:①提高代码的复用率
           ②让代码看起来更优雅
           ③让代码更可读

2. 协议的规则:在一个类里实现了__enter__和__exit__的方法

“””处理数据库上下文的管理器”””
import pymysql

class UseDatabase:
    def __enter__(self):
        # 连接数据库
        self.conn = pymysql.connect(‘127.0.0.1’, ‘root’, ‘root’, ‘test’)
        self.cursor = self.conn.cursor()
        return self.cursor      #无return,就没办法使用当前对象

    def __exit__(self, exc_type, exc_val, exc_tb):  #关闭退出时可能发出异常,处理异常
        self.conn.commit()
        self.cursor.close()
        self.conn.close()

 

#flask_test
import area as area
from flask import Flask,render_template,request   #渲染模板
import math
import re
import pymysql
from DBcm import UseDatabase

app = Flask(__name__)

@app.route(‘/hello’)
def first_flask():
    return “hello”

@app.route(‘/enter’)
def enter_page():
    return render_template(‘enter.html’,
                           the_title=’主页’,)

@app.route(‘/area’,methods=[‘POST’])
def area_page():
    radius = request.form[‘radius’]
    if radius == ” or radius.isspace == None:
        radius = 0
    if re.match(‘([0-9]|\.){‘+str(len(radius))+’}’,radius) == None:
        radius = 0
    area = round(math.pi*float(radius)**2,3)
    ”’
    mysql学习
    ”’
    with UseDatabase() as cursor:

        # 数据库文件读写
        sql = ”’insert into mysql1(radius,browser_string,area) values(%s,%s,%s)”’
        cursor.execute(sql, (float(radius), str(request.user_agent), str(area)))

    return render_template(‘area.html’,
                                the_radius=radius,
                                the_area=area, )

@app.route(‘/file_out’)
def file_out_page():
    with UseDatabase() as cursor:
        # 数据库文件读写
        sql=”””select radius,browser_string,area from mysql1″””
        cursor.execute(sql)
        result = cursor.fetchall()
    return render_template(‘file1_out.html’,
                           file1=result)

if __name__==’__main__’:
    app.run(debug=True)

 

3.生成器函数实现上下文管理器:

生成器函数(带有yield的函数),结合装饰器===》与return不同,yield是返一个函数,return是返回值

 

0x0C 函数修饰符

函数修饰符作用:为现有函数增加功能而不必修改现有函数代码

    ①修饰符是一个函数
    ②修饰符取被修饰函数为参数
    ③修饰符返回一个新函数
    ④修饰符维护被修饰函数的签名(参数)

 

“””函数修饰符”””

#定义函数修饰符
from functools import wraps
def test_decorator(func):
  @wraps(func)                           #可以维护被修饰函数的属性
    def wrapper(*args,**kwargs):           #参数长度不固定,一个关键字=》*args
      print(“****开始****”)               #参数为键值对,接收任意多个关键字参数
        func(*args,**kwargs)
        print(‘****结束****’)
    return wrapper

@test_decorator
def hello(name,age):
    print(‘你好呀,小哥哥,我是:’,name,age)

hello(name=’lily’,age=12)

0x0D 异常处理

1. 异常类

  • 所有异常都是基类Exception的成员,它们都定义在exceptions模块中。
  • 如果这个异常对象没有进行处理和捕捉,程序就会用所谓的回溯(traceback, 一种错误信息)终止执行,这些信息包括错误的名称(例如NameError)、原因和错误发生的行号。
  • 语法错误。索引错误。keyError。文件名不存在。

 2. 关键字及案例

try 语句按照如下方式工作;
  • 首先,执行 try 子句(在关键字 try 和关键字 except 之间的语句)。
  • 如果没有异常发生,忽略 except 子句,try 子句执行后结束。
  • 如果在执行 try 子句的过程中发生了异常,那么 try 子句余下的部分将被忽略。如果异常的类型和 except 之后的名称相符,那么对应的 except 子句将被执行。
  • 如果一个异常没有与任何的 except 匹配,那么这个异常将会传递给上层的 try 中。
      一个 try 语句可能包含多个except子句,分别来处理不同的特定的异常。最多只有一个分支会被执行。处理程序将只针对对应的 try 子句中的异常进行处理,而不是其他的 try 的处理程序中的异常。

“””异常案例:division by zero”””

number = int(input(‘输入被除数’))
try:
    x = 1/number
except Exception as e:
    print(e)

“””异常案例:unsupported operand type(s) for /: ‘int’ and ‘str'”””
try:
    number = input(‘输入被除数’)

    x = 1/number
except Exception as e:
  print(e)

“””异常案例”””

number = int(input(‘输入被除数’))
try:
    x = 1/number
except Exception as e:
    print(e)
else:
    print(“否则”)           #没错会执行
finally:
    print(“执行完成”)       #不管执行有无错误,都会执行

3. raise:手动抛出异常

    raise语法格式如下:raise [Exception [, args [, traceback]]]
    raise 唯一的一个参数指定了要被抛出的异常。它必须是一个异常的实例或者是异常的类(也就是 Exception 的子类)。如果你只想知道这是否抛出了一个异常,并不想去处理它,那么一个简单的 raise 语句就可以再次把它抛出。
>>> try:
        raise NameError(‘HiThere’)
    except NameError:
        print(‘An exception flew by!’)
        raise
   
An exception flew by!
Traceback (most recent call last):
  File “<stdin>”, line 2, in ?
NameError: HiThere

4. assert:断言 ===> assert 1==3

     assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常。
    断言可以在条件不满足程序运行的情况下直接返回错误,而不必等待程序运行后出现崩溃的情况,例如我们的代码只能在 Linux 系统下运行,可以先判断当前系统是否符合条件
assert expression <==> if not expression:
                                       raiseAssertionError
assert 后面也可以紧跟参数:

 

>>> assert True     # 条件为 true 正常执行
>>> assert False    # 条件为 false 触发异常
Traceback (most recent call last):
  File “<stdin>”, line 1, in <module>
AssertionError
>>> assert 1==1    # 条件为 true 正常执行
>>> assert 1==2    # 条件为 false 触发异常
Traceback (most recent call last):
  File “<stdin>”, line 1, in <module>
AssertionError

>>> assert 1==2, ‘1 不等于 2’
Traceback (most recent call last):
  File “<stdin>”, line 1, in <module>
AssertionError: 1 不等于 2

5. 自定义异常:

可以通过创建一个新的异常类来拥有自己的异常。异常类继承自 Exception 类,可以直接继承,或者间接继承。当创建一个模块有可能抛出多种不同的异常时,一种通常的做法是为这个包建立一个基础异常类,然后基于这个基础类为不同的错误情况创建不同的子类

6. 异常抛出原则:

精确:只对可能产生异常的代码,进行异常处理
抽象级别:  抛出的异常与自己的抽象级别对应
with语句更优雅: 上下文管理器更优雅处理异常

0x0E 总结

因为才接触Python,想要记录的太多了,导致文章篇幅很大,感谢愿意看到文末的你啦。。。作为一个才学习Python的小菜鸡,我觉得学习一门语言,最重要的是学习如何去使用他的库、类。。好好的读懂如何利用API文档比买很多其他的书都还来的有用。。

奉上集齐所有API的网站链接(希望能帮到你哟):https://tool.oschina.net/apidocs

这个链接是朋友发给我的关于Python学习的:http://c.biancheng.net/python/

不知道有没有小哥哥或者小姐姐能带我打CTF,练习场附上:https://ctf.wgpsec.org/challenges

学安全,菜是原罪。。。所以,一起加油吧,顶端相见

来源:freebuf.com 2020-08-01 19:26:10 by: MoLing

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论