0x00 简单介绍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.时间复杂度和空间复杂度(判断一个算法是否优秀的标准)
0x01 Flask制作一个Web应用
1. Flask框架介绍:(微框架)
pip install flask -i https://mirrors.aliyun.com/pypi/simple
#flask_test
from flask import Flask
app = Flask(__name__)
def first_flask():
return "hello"
app.run()
2. 应用案例
需要建一个符合Flask框架要求的文件夹子,里面包含:static文件夹(存储静态文件);tenplates文件夹(存放模板文件)
#flask_test
from flask import Flask,render_template #渲染模板
app = Flask(__name__)
def first_flask():
return "hello"
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__)
def first_flask():
return "hello"
def enter_page():
return render_template('enter.html', the_title='主页',)
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)
0x02 存储数据
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
'/hello') .route(
def first_flask():
return "hello"
'/enter') .route(
def enter_page():
return render_template('enter.html',
the_title='主页',)
'/area',methods=['POST']) .route(
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,)
'/file_out') .route(
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
def first_flask():
return "hello"
def enter_page():
return render_template('enter.html',
the_title='主页',)
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,)
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',
file1=file)
#print(log)
#return str(log)
if __name__=='__main__':
app.run(debug=True)
0x03 数据库管理数据
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__)
'/hello') .route(
def first_flask():
return "hello"
'/enter') .route(
def enter_page():
return render_template('enter.html',
the_title='主页',)
'/area',methods=['POST']) .route(
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, )
'/file_out') .route(
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)
0x04 面向对象
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)
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相关联的值。同样,仅当对象可变的时候,才需要实现这个方法。
0x05 上下文管理协议
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是返回值
0x06 函数修饰符
函数修饰符作用:为现有函数增加功能而不必修改现有函数代码
①修饰符是一个函数
②修饰符取被修饰函数为参数
③修饰符返回一个新函数
④修饰符维护被修饰函数的签名(参数)
"""函数修饰符"""
#定义函数修饰符
from functools import wraps
def test_decorator(func):
@wraps(func) #可以维护被修饰函数的属性
def wrapper(*args,**kwargs): #参数长度不固定,一个关键字=》*args
print("****开始****") #参数为键值对,接收任意多个关键字参数
func(*args,**kwargs)
print('****结束****')
return wrapper
def hello(name,age):
print('你好呀,小哥哥,我是:',name,age)
hello(name='lily',age=12)
0x07 异常处理
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 后面也可以紧跟参数:
# 条件为 true 正常执行 > assert True
# 条件为 false 触发异常 > assert False
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
1==1 # 条件为 true 正常执行 > assert
1==2 # 条件为 false 触发异常 > assert
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError
1==2, '1 不等于 2' > assert
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError: 1 不等于 2
5. 自定义异常:
可以通过创建一个新的异常类来拥有自己的异常。异常类继承自 Exception 类,可以直接继承,或者间接继承。当创建一个模块有可能抛出多种不同的异常时,一种通常的做法是为这个包建立一个基础异常类,然后基于这个基础类为不同的错误情况创建不同的子类
6. 异常抛出原则:
精确:只对可能产生异常的代码,进行异常处理
抽象级别: 抛出的异常与自己的抽象级别对应
with语句更优雅: 上下文管理器更优雅处理异常
0x08 总结
因为才接触Python,想要记录的太多了,导致文章篇幅很大,感谢愿意看到文末的你啦。。。程序猿哥哥说学习一门语言,最重要的是学习如何去使用他的库、类。。好好的读懂如何利用API文档比买很多其他的书都还来的有用。。
奉上所有python的学习资料(视频和编程语言api文档的链接),后台回复“python学习包”,即可获得啦~~~
学安全,菜是原罪。。。所以,一起加油吧,顶端相见
本文始发于微信公众号(凌晨安全):python学习之路----python基础(下)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论