Python Web编程笔记
1 .多任务编程—进程
1.1 多任务介绍
多任务:在同一时间内执行多个任务
目的:充分利用CPU资源,提高程序的执行效率
并发:
在一段时间内交替去执行多个任务(只有一个CPU)
并行:
在同一时刻执行多个任务(多核CPU)
1.2 进程
进程:在运行的程序
进程:操作系统分配资源的最小单位
线程:执行利用资源的基本单位
1.3 多进程的使用流程
-
导入模块(multiprocessing)
-
创建子进程(Process)
-
开启子进程(start)
import time
# 1.导入模块
import multiprocessing
def dance():
for i in range(5):
time.sleep(1)
print('跳舞', i)
def sing():
for i in range(5):
time.sleep(1)
print('唱歌', i)
if __name__ == '__main__':
# 单进程 需要10秒钟完后
# 最少有一个进程 这个进程中最少有一个线程
# 多进程 需要5秒钟完成
# (注意点)
# 三个进程:1个主进程,2个子进程
# 三个线程:每个进程里有一个线程
# 2.创建子进程
# Process:
# target: 指定执行的任务名(函数名)
my_dance = multiprocessing.Process(target=dance)
my_sing = multiprocessing.Process(target=sing)
# 3.开始子进程(如果不开启是不会执行子进程的)
my_dance.start()
my_sing.start()
# dance()
# sing()
1.4 进程编号
目的:知道子进程是由哪个主进程创建的(子进程需要父进程回收资源)
os.getpid() 表示获取当前进程编号
os.getppid() 表示获取当前父进程编号
import os
import time
# 1.导入模块
import multiprocessing
def dance():
# 获取子进程id
print('dance子进程id:', os.getpid())
# 获取父进程id
print('dance父进程id:', os.getppid())
def sing():
# 获取子进程id
print('sing子进程id:', os.getpid())
# 获取父进程id
print('sing父进程id:', os.getppid())
if __name__ == '__main__':
# 获取主进程的id
print('主进程id:', os.getpid())
# 2.创建子进程
# Process:
# target: 指定执行的任务名(函数名)
my_dance = multiprocessing.Process(target=dance)
my_sing = multiprocessing.Process(target=sing)
# 3.开始子进程(如果不开启是不会执行子进程的)
my_dance.start()
my_sing.start()
获取进程名
import multiprocessing
def dance():
# 获取进程名字
print(multiprocessing.current_process())
for i in range(5):
print('跳舞')
if __name__ == '__main__':
# 创建子进程
# Process:
# target:指定任务名
# name:子进程起名
my_dance = multiprocessing.Process(target=dance, name='老王')
# 开启
my_dance.start()
结果
默认为-1
1.5 执行带有参数的进程
# 1. 导入模块
import multiprocessing
# 带有参数的函数
def dance(count):
for i in range(count):
print('跳舞')
if __name__ == '__main__':
# 2. 创建子进程
# 带有参数的函数:
# args: 元组 (单个元素的元组有,)
# kwargs: 字典(key值要和函数中的形参完全重名才行)
my_dance = multiprocessing.Process(target=dance, args=(5,))
my_dance = multiprocessing.Process(target=dance, kwargs={'count': 5})
# 3. 开启
my_dance.start()
1.6 多进程注意点
-
每个进程都有自己的独立空间,进程之间无共享全局变量
-
结论:主进程默认会等待子进程结束之后再结束
让子进程随着主进程的结束而结束
(1) 守护进程(在start之前设置)
my_func.daemon = True
(2) 手动结束子进程
my_func.terminate()
# 让子进程随着主进程结束而结束的两种方式 # 1. 守护进程:子进程对象.daemon = True # 2. 手动设置:子进程对象.terminate() import multiprocessing import time def func(): for i in range(5): time.sleep(0.2) print('func') if __name__ == '__main__': # 主进程会等待子进程结束之后再结束 # 程序一旦运行,就会默认创建主进程 my_func = multiprocessing.Process(target=func) # 方式一 设置守护进程,需要在start之间设置,否则无效 # my_func.daemon = True my_func.start() # 主进程开启了子进程 time.sleep(0.5) # 方式二:手动设置 my_func.terminate() print('主进程:over') exit()
2.多任务编程—线程
2.1 进程和线程的关系
线程是使用资源的最小单位==>依附于进程
2.2 多线程的使用
-
导入模块(threading)
-
创建子进程(Thread)
-
开启子进程(start)
import time # 1.导入模块 import threading def dance(): for i in range(5): print('跳舞', i) time.sleep(1) def sing(): for i in range(5): print('唱歌', i) time.sleep(1) if __name__ == '__main__': # # 2.创建子线程 # Process: # target: 指定执行的任务名(函数名) my_dance = threading.Thread(target=dance) my_sing = threading.Thread(target=sing) # 3.开始子线程 my_dance.start() my_sing.start()
2.3 执行带有参数的进程
# 1.导入模块
import threading
def dance(count):
for i in range(count):
print('跳舞', i)
if __name__ == '__main__':
# 2.创建子线程
# args
my_dance = threading.Thread(target=dance, args=(5,))
# kwargs
my_dance = threading.Thread(target=dance, kwargs={'count': 5})
# 3.开始子线程
my_dance.start()
2.4注意点
-
线程之间的执行是无序的
-
主线程会等待子线程的结束而结束
设置守护进程
(1)Thread(deamon = True)
my_func = threading.Thread(target=func, daemon=True)
(2) setDaemon
my_func.setDaemon(True)
-
线程共享全局变量
由于线程依附于进程,一个进程的所有的线程都是使用的同一片内存空间
所以:一个进程的线程是共享全局变量的
import threading
import time
g_num = []
def write():
global g_num
for i in range(5):
g_num.append(i)
print('write:', g_num)
def read():
global g_num
print('read:', g_num)
if __name__ == '__main__':
my_write = threading.Thread(target=write)
my_read = threading.Thread(target=read)
my_write.start()
time.sleep(1)
my_read.start()
2.5线程共享全局变量问题解决方案
1. 线程等待 线程对象.join()
-
互斥锁
对共享的数据进行锁定,保证同一时刻只能有一个线程去操作
互斥锁的使用
# 1.创建锁 mutex = threading.Lock() # 2.上锁 mutex.acquire() # 3.释放锁 mutex.release()
import threading import time g_num = 0 # 1. 创建锁 mutex = threading.Lock() def sum_num1(): global g_num # 2. 上锁 mutex.acquire() for i in range(1000): g_num += 1 # 3.解锁 mutex.release() print('sum_num1', g_num) def sum_num2(): global g_num # 2. 上锁(同一把锁 必须先解锁才可以上锁) mutex.acquire() for i in range(1000): g_num += 1 # 3.解锁 mutex.release() print('sum_num2', g_num) if __name__ == '__main__': sub_num1 = threading.Thread(target=sum_num1) sub_num2 = threading.Thread(target=sum_num2) sub_num1.start() # 让主进程等待sub_num1执行完毕以后再继续执行 # sub_num1.join() sub_num2.start()
3. 网络编程
3.1 ip地址
在网络中表示唯一一台设备
-
查看ip地址:
win: ipconfig
mac和linux: ifconfig
-
测试网络是否畅通:
ping IP地址
-
本机ip地址
127.0.0.1
3.2 端口和端口号
端口号:标识一台网络设备中的一个程序
端口号的分类:
知名端口号:0~1023
动态端口号:1024~65535
3.3 TCP介绍
TCP:是一种面向连接的,可靠的,可以把数据准确污无误的传输控制协议
可靠传输:
1. TCP采用发送应答机制
2. 超时重传
3. 错误校验
4. 流量控制和拥塞管理
3.4 socket(套接字)
socket:进程之间的通信工具
3.5 TCP网络应用程序开发流程
3.6 TCP客户端程序开发
基本流程
- 创建客户端套接字对象
- 和服务器套接字建立连接
- 发送数据
- 接受数据
- 关闭客户端套接字
编解码
网络中必须传输二进制的数据
字符串转化为二进制 encode(‘utf-8’)
二进制转化为字符串 decode(‘utf-8’)
注意:utf8编码的数据必须用utf-8解码
import socket
# 1. 创建客户端套接字对象
# 参数1: ipv4 ip协议的版本
# 参数2: 选择协议(SOCK_STREAM==>tcp协议)
tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. 和服务器套接字建立连接
# 参数: 元组(有两个元素)
# 元素1:服务器的ip地址(字符串)
# 元素2:服务器的端口号(数字)
tcp_client_socket.connect(("192168.144.29", 8080))
# 3. 发送数据 需要先转化为二进制
tcp_client_socket.send("123".encode('utf-8'))
# 4. 接受数据
# 参数:以字节为单位的接受的数据大小
# 注意:recv会阻塞等待数据的到来
recv_data = tcp_client_socket.recv(1024)
# 解码
recv_data = recv_data.decode('utf-8')
print(recv_data)
# 5. 关闭客户端套接字
tcp_client_socket.close()
3.7 TCP服务端开发
基本流程
- 创建服务端端套接字对象
- 绑定端口号
- 设置监听
- 等待接受客户端的连接请求
- 接受数据
- 发送数据
- 关闭套接字
import socket
# 1. 创建服务端端套接字对象
# 参数1: ipv4 ip协议的版本
# 参数2: 选择协议(SOCK_STREAM==>tcp协议)
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2. 绑定端口号
# 参数: 元组(有两个元素)
# 元素1:服务器的ip地址(字符串)
# 元素2:服务器的端口号(数字)
# 不写默认本机ip地址
tcp_server_socket.bind("192.168.144.28", 8080)
# 3. 设置监听
# 参数: 最大监听个数(排队处理的最大等待数量)
# tcp_server_socket从主动套接字变成了被动套接字
tcp_server_socket.listen(128)
# 4. 阻塞等待接受客户端的连接请求
# 返回值是一个元组
# 元素1 客户端socket
# 元素2 客户端的ip地址和端口号
# 返回值是一个元组,通过拆包语法 我们分别获取了 元素1和元素2
client_socket,client_addr = tcp_server_socket.accept()
# 5. 接受数据
# 参数:接受数据的大小(字节)
client_data = client_socket.recv(1024)
# 对二进制的数据解码
client_data = client_data.decode()
print(client_data)
# 6. 发送数据
send_data = "123".encode()
client_socket.send(send_data)
# 7. 关闭套接字
client_socket.close()
tcp_server_socket.close()
端口复用
# 端口复用设置
# setsockopt:设置socket选项
# 参数1: socket选项列表(SOL)
# 参数2: 地址复用
# 参数3:True开启选项 False:不开启选项(默认)
tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, True)
判断客户端关闭和循环接受
while True:
# 5. 接受数据
# 参数:接受数据的大小(字节)
client_data = client_socket.recv(1024)
# 如果接受到的数据长度为0 则证明客户端关闭
if len(client_data) == 0:
print('客户端关闭!!!')
break
# 对二进制的数据解码
client_data = client_data.decode()
print(client_data)
# 6. 发送数据
send_data = "123".encode()
client_socket.send(send_data)
函数版本
import socket
def handler_client_request(client_socket):
"""处理客户端的请求"""
while True:
# 5. 接受数据
# 参数:接受数据的大小(字节)
client_data = client_socket.recv(1024)
# 如果接受到的数据长度为0 则证明客户端关闭
if len(client_data) == 0:
print('客户端关闭!!!')
break
# 对二进制的数据解码
client_data = client_data.decode()
print(client_data)
# 6. 发送数据
send_data = "123".encode()
client_socket.send(send_data)
client_socket.close()
def main():
# 1. 创建服务端端套接字对象
# 参数1: ipv4 ip协议的版本
# 参数2: 选择协议(SOCK_STREAM==>tcp协议)
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 端口复用设置
# setsockopt:设置socket选项
# 参数1: socket选项列表(SOL)
# 参数2: 地址复用
# 参数3:True开启选项 False:不开启选项(默认)
tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, True)
# 2. 绑定端口号
# 参数: 元组(有两个元素)
# 元素1:服务器的ip地址(字符串)
# 元素2:服务器的端口号(数字)
# 不写默认本机ip地址
tcp_server_socket.bind("192.168.144.28", 8080)
# 3. 设置监听
# 参数: 最大监听个数(排队处理的最大等待数量)
# tcp_server_socket从主动套接字变成了被动套接字
tcp_server_socket.listen(128)
while True:
# 4. 阻塞等待接受客户端的连接请求
# 返回值是一个元组
# 元素1 客户端socket
# 元素2 客户端的ip地址和端口号
# 返回值是一个元组,通过拆包语法 我们分别获取了 元素1和元素2
client_socket,client_addr = tcp_server_socket.accept()
# 处理客户端请求
handler_client_request(client_socket)
# 7. 关闭套接字
client_socket.close()
tcp_server_socket.close()
if __name__ == '__main__':
main()
多任务版本
import socket
import multiprocessing
def handler_client_request(client_socket):
"""处理客户端的请求"""
while True:
# 5. 接受数据
# 参数:接受数据的大小(字节)
client_data = client_socket.recv(1024)
# 如果接受到的数据长度为0 则证明客户端关闭
if len(client_data) == 0:
print('客户端关闭!!!')
break
# 对二进制的数据解码
client_data = client_data.decode()
print(client_data)
# 6. 发送数据
send_data = "123".encode()
client_socket.send(send_data)
client_socket.close()
def main():
# 1. 创建服务端端套接字对象
# 参数1: ipv4 ip协议的版本
# 参数2: 选择协议(SOCK_STREAM==>tcp协议)
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 端口复用设置
# setsockopt:设置socket选项
# 参数1: socket选项列表(SOL)
# 参数2: 地址复用
# 参数3:True开启选项 False:不开启选项(默认)
tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, True)
# 2. 绑定端口号
# 参数: 元组(有两个元素)
# 元素1:服务器的ip地址(字符串)
# 元素2:服务器的端口号(数字)
# 不写默认本机ip地址
tcp_server_socket.bind("127.0.0.1", 8080)
# 3. 设置监听
# 参数: 最大监听个数(排队处理的最大等待数量)
# tcp_server_socket从主动套接字变成了被动套接字
tcp_server_socket.listen(128)
while True:
# 4. 阻塞等待接受客户端的连接请求
# 返回值是一个元组
# 元素1 客户端socket
# 元素2 客户端的ip地址和端口号
# 返回值是一个元组,通过拆包语法 我们分别获取了 元素1和元素2
client_socket,client_addr = tcp_server_socket.accept()
# 创建了一个子进程
sub_process = multiprocessing.Process(target=handler_client_request, args=(client_socket, ))
# 开启子进程
sub_process.start()
# 7. 关闭套接字
client_socket.close()
tcp_server_socket.close()
if __name__ == '__main__':
main()
3.8 TCP socket send和recv原理
4. HTTP协议和静态Web服务器
4.1 HTTP协议
tcp协议是我们大多数网络应用之间的连接时候使用的协议(底层协议)
http协议的作用:特指浏览器和服务器之间的数据通信格式的具体规定
超文本传输协议
注意:http协议规定的就是send和recv 接受和发送数据的具体格式
4.2 url
统一资源定位符:URL
组成:例如:https://news.163.com/18/1122.html
- 协议部分:https:// http:// ftp://
- 域名部分:news.163.com
- 资源路径部分:/18/1122.html
4.3 http协议的通信过程
4.4 HTTP请求报文
发送数据:请求报文
回复数据:应答报文
请求报文方式:
-
GET方式:获取web服务器数据,只向服务器要数据,不给服务器提供数据
-
POST方式:会给服务器提供数据
请求报文的组成:请求行 请求头 空行 请求体(get方式没有请求体)
请求行:
GET /index.html HTTP/1.1 \r\n 请求方式 请求资源路径 协议版本 换一行
请求头:
key:value \r\n 设置网页相关的属性
空行:
\r\n
请求体:
想要给服务器传递的数据
4.5 应答报文
组成:应答行 应答头 空行 应答体
应答行:
HTTP/1.1 200 OK HTTP \r\n 协议版本 状态码 状态描述 换行
应答头:
key:value \r\n 设置应答数据的相关属性 换行
空行:
\r\n
应答体:
html jpg 视频 服务器发给浏览器的数据
4.6 静态web服务器
函数版本
import socket
def handler_client_request(client_socket):
"""和浏览器进行数据交互的函数
:param client_socket:
:return:
"""
# 接受数据
recv_data = client_socket.recv(10000000)
if len(recv_data) == 0:
print('客户端关闭')
return
# 解码
recv_data = recv_data.decode()
# 对请求报文进行切割
path_list = recv_data.split(" ")
# 请求资源路径
request_path = path_list[1]
path_list[1]
# 发送数据
# 异常捕获(防止出现异常的时候,服务器直接崩溃)
try:
# 打开资源文件
f = open('./static' + request_path, 'rb')
# 存放了图片资源
file_data = f.read()
f.close()
except Exception as e:
# 浏览器访问的网址里的不存在的情况下
# 证明:文件不存在
print("异常信息:", e)
# 访问不成功的情况下的响应报文
response_line = "HTTP/1.1 404 NOT FOUND\r\n"
response_hander = "server:pu1.0\r\n"
response_body = "not found i am sorry!!!"
# 把没有找到相应的文件的这个信息发送给浏览器
response_data = response_line + response_hander + "\r\n" + response_body
client_socket.send(response_data.encode())
client_socket.close()
else:
# 浏览器访问的网址里的资源存在的情况下
# 响应行
response_line = "HTTP/1.1 200 OK\r\n"
response_hander = "server:pu1.0\r\n"
response_body = file_data
# 响应数据
response_data = (response_line + response_hander + "\r\n").encode() + response_body
# 发送数据
client_socket.send(response_data)
client_socket.close()
def main():
"""控制整个服务器流程的函数
tcp_server_socket:用来就收链接的socket
client_socket:用来处理和浏览器之间的数据交流的socket
"""
# 创建电话
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 端口复用
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 绑定地址
tcp_server_socket.bind(("", 8080))
# 设置监听
tcp_server_socket.listen(128)
while True:
# 接受连接请求
client_socket, addr = tcp_server_socket.accept()
# 调用浏览器请求的函数
handler_client_request(client_socket)
if __name__ == '__main__':
main()
最终版本:终端启动,面向对象,异常处理,多任务
import socket
import multiprocessing
import sys
class WebServer:
# 初始化方法
def __init__(self, port=8080):
# 创建电话
self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 端口复用
self.tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 绑定地址
self.tcp_server_socket.bind(("", int(port)))
# 设置监听
self.tcp_server_socket.listen(128)
@staticmethod
def handler_client_request(client_socket):
"""和浏览器进行数据交互的函数
:param client_socket:
:return:
"""
# 接受数据
recv_data = client_socket.recv(10000000)
if len(recv_data) == 0:
print('客户端关闭')
return
# 解码
recv_data = recv_data.decode()
# 对请求报文进行切割
path_list = recv_data.split(" ")
# 请求资源路径
request_path = path_list[1]
path_list[1]
# 发送数据
# 异常捕获(防止出现异常的时候,服务器直接崩溃)
try:
# 打开资源文件
f = open('./static' + request_path, 'rb')
# 存放了图片资源
file_data = f.read()
f.close()
except Exception as e:
# 浏览器访问的网址里的不存在的情况下
# 证明:文件不存在
print("异常信息:", e)
# 访问不成功的情况下的响应报文
response_line = "HTTP/1.1 404 NOT FOUND\r\n"
response_hander = "server:pu1.0\r\n"
response_body = "not found i am sorry!!!"
# 把没有找到相应的文件的这个信息发送给浏览器
response_data = response_line + response_hander + "\r\n" + response_body
client_socket.send(response_data.encode())
client_socket.close()
else:
# 浏览器访问的网址里的资源存在的情况下
# 响应行
response_line = "HTTP/1.1 200 OK\r\n"
response_hander = "server:pu1.0\r\n"
response_body = file_data
# 响应数据
response_data = (response_line + response_hander + "\r\n").encode() + response_body
# 发送数据
client_socket.send(response_data)
client_socket.close()
def start(self):
"""控制整个服务器流程的函数
tcp_server_socket:用来就收链接的socket
client_socket:用来处理和浏览器之间的数据交流的socket
"""
while True:
# 接受连接请求
client_socket, addr = self.tcp_server_socket.accept()
# 创建多进程
sub_process = multiprocessing.Process(target=self.handler_client_request, args=(client_socket, ))
sub_process.start()
# 调用浏览器请求的函数
self.handler_client_request(client_socket)
if __name__ == '__main__':
# 获取动态端口
if len(sys.argv) != 2:
print("正确的格式是 python3 文件名 端口号!!!")
else:
port = sys.argv[1]
web_server = WebServer(int(port))
web_server.start()
5. 数据库
5.1 数据库
分类:关系型数据库、非关系型数据库
本质上:一种特殊的文件
数据库指的实际上是一个很多功能的整体:
- 数据库是由数据表组成的
- 数据表是用来存储数据的
- 存储一类相同信息的一列:字段
- 存储某个人活着事务详细信息的一行:记录
- 能够标识唯一一行记录的字段:主键(不能为空,不可重复)
- 表和表之间具有一定的关联的数据:关系型数据库
特点:持久化存储、读写速度极高、保证数据的有效性
关系型数据库管理系统:RDBMS
5.2 MySQL数据类型和约束
数据类型
- 整数:int,bit
- 小数:decimal
- 字符串:varchar ,char
- 日期时间:date,time,datetime
- 枚举类型:enum
数据约束
5.3 MySQL数据库操作
-- 链接数据库
mysql -uroot -pmysql
-- 不显示密码
mysql -uroot -p
-- 退出数据库
quit/ctrl+d/exit
-- 显示数据库版本
select version();
-- 显示时间
select now();
-- 查看当前使用的数据库
select database();
-- 查看所有的数据库
show databases;
-- 创建数据库
create database 数据库名字 charset = utf-8;
-- 查看创建数据库的语句
show create database 数据库名字
-- 删除数据库
drop database 数据库名
-- 使用数据库
use 数据库的名字
5.4 MySQL数据表操作
-- 查看当前数据表
show tables;
-- 创建表(子段后必须先写数据类型,数据类型必须有)
-- create table 数据表名(字段 类型 约束);
-- auto_increment 自动增长
create table xxx(
id int unsigned primary key auto_increment,
name varchar(30) not null
);
-- 查看标的结构
desc 数据表的名字;
-- 查看表的创建语句
show create table 表名;
-- 修改表-添加字段
alter table 表名 add 列名 类型;
-- 修改表-修改字段 不重命名
alter table 表名 modify 列名 类型及约束;
-- 修改表-修改字段 重命名
alter table 表名 change 原名 新名 类型及约束;
-- 修改表-删除字段
alter table 表名 drop 列名;
-- 删除
drop table 表名;
drop database 数据库;
5.4 MySQL增删改查
-- 增加
-- 全列插入
insert [into] 表名 values(...)
-- 主键字段可以用 0 null default 来占位
-- 部分插入 不能为空必须插入
insert into 表名(列1,...) values(值1,...)
-- 多行插入
insert into 表名 values(...),(...);
-- 修改
update 表名 set 列1=值1,列2=值2... where 条件;
-- 查询基本使用
-- 查询所有列
select * from 表名;
-- 定条件查询
select * from 表名 where 条件;
-- 查询指定列
select 列1,列2... from 表名;
-- 可以使用as作为列或表指定别名,给表起别名必须使用
select 字段[as 列名],字段[as 别名] from 数据表;
-- 消除重复行 distinct
select distinct gender from stduent;
-- 删除
-- 物理删除
delete from 表名 where 条件;
-- 逻辑删除
-- 用一个字段来表示 这条信息是否已经不能再使用了
查询:
-- 条件查询
-- 比较运算符 > < >= <= = !=或者<> 等于为=
-- 大于18岁
select * from students where age>=18;
-- 逻辑运算符
-- and or not
-- 模糊查询
-- like % 替换任意个 _替换一个
select * from student where name like "小%";
-- 范围查询
-- in (1, 3, 8)表示一个非连续的范围内
-- 查询年龄为18或24的姓名
select name from students where age in (18,34);
-- not in 不非连续的范围之内
-- 年龄不是18或34岁的信息
select * from students where age not in (18,34);
-- between and 一个连续的范围
-- 年龄是18到34岁的信息
select * from students where age between 18 and 24;
-- not between and 不在一个连续的范围
-- 年龄不是18或34岁的信息 不需要加()
select * from students where age not between 18 and 24;
-- 判空 is null
select * from students where height is null;
-- is not null
select * from students where height is not null;
-- 排序查询
-- order by
-- asc 升序默认 desc 降序
-- 查询年龄在18到24岁的男性,按照年龄从小到大排序
select * from students where (age between 18 and 24) and gender=1 order by age asc;
-- order by 多个字段 加个,号
-- 查询年龄在18到24岁的女,身高从高到低,身高相同时,按照年龄从大到小排序
select * from students where (age between 18 and 24) and gender=2 order by height desc,age desc;
-- 聚合函数 组函数 一般结合group by 来使用
-- count:总数
-- 查询男性有多少人
select count(*) from students where gender=1;
-- max:最大值
-- 查询最大年龄
select max(age) from students;
-- min:最小值
-- 查询最小年龄
select min(age) from students;
-- sun:求和 可以是表达式
-- 计算所有人年龄的总和
select sum(age) from students;
-- avg:求平均值
-- 计算平均年龄
select sum(age)/count(*) from students;
-- 四舍五入 round(123.23, 1) 保留一位小数
-- 分页查询:限制显示的数量
-- limit start, count
-- start :(页数-1)*每一页的数量
-- 查询前5个数据
select * from students limit 5;
-- 每页显示2个,第1个页面
select * from students limit 0,2;
-- 每页显示2个,第2个页面
select * from students limit 2,2;
-- 每页显示2个,第3个页面
select * from students limit 4,2;
-- limit放在最后边
-- 分组查询
-- 按照性别分组,查询所有的性别
-- 按照字段分组,就可以查询什么字段
select gender from students group by gender;
-- group_concat
-- 查询同种性别中的姓名
select gender,group_concat(name) from students group by gender;
-- 计算每种性别的人数
select gender,count(*) from students group by gender;
-- having 对每个组进行筛选
-- 查询平均年龄超过30岁的性别,姓名
select gender,group_concat(name) from students group by gender having avg(age)>30;
-- 查询每种性别中的人数多于2个的性别和姓名
select gender,group_concat(name) from students group by gender having count(*)>2;
-- 子查询
-- 标量子查询:子查询返回的结果是一个数据(一行一列)
-- 行子查询:子查询返回的结果是一个行(一行多列)
-- 列子查询:子查询返回的结果是一个列(一列多行)
-- 查询出高于平均身高的信息
select * from stduents where height>(select avg(height) from students);
连接查询:将多张表连接成一个大的数据集进行汇总显示
-
内连接: 两个表的交集 inner join
-- select 字段 from 表1 inner join 表B on 条件(表1.字段=表2.字段); -- 查询有能够对应班级的学生以及班级信息 select * from students inner join classes on students.cls_id=classes.id; -- 别名 select * from students as s inner join classes as c on s.cls_id=c.id;
-
外连接:
-
左外连接:交集和左边表特有的数据(左边的表为主表和两个表的交集)
-
右外连接:交集和右边表特有的数据(右边的表为主表和两个表的交集)
-- 左连接:主表 left join 从表 on 连接条件 -- 右连接:从表 right join 主表 on 连接条件 -- 查询 没有能够对应班级的学生 select * from students left join classes on students.cls_id=classes.id where classes.name is NUll;
-
-
自连接:只需要使用一个表,可以加开查询速度,减少数据表占用空间
-- 把一张表假设为两张一样的表,然后再做多表查询 -- 将areas表取两个别名 -- 连接的表按照条件 进行内连接 -- 查找出需要的字段 select city* from areas as city inner join areas as province on city.id=province.aid where province.atitle='广东省';
5.7 数据库设计的三范式
范式:数据库合理性的规范
- 第一范式:字段不能再分,列不能再分,原子性
- 第二范式:满足1NF,表必须有主键;非主键字段 必须完全依赖于主键 不能出现部分从属(数据冗余)
- 第三范式:满足2NF,非主键必须直接依赖于主键,不能存在传递依赖(数据冗余)
E-R模型:描述数据库存储数据的结构模型
- 实体:矩形
- 属性:椭圆形
- 关系:菱形 (一对一,一对多,多对多)
5.7 分表操作和外键
分表操作
外键
大型项目不建议:插入速度慢
5.8 PyMySQL的使用
import pymysql
# 1 建立连接
conn = pymysql.connect(host='localhost', port=3306,user='root',password='mysql',database='jing_dong' charset='utf-8')
# 2 创建游标 游标可以记录获取数据的个数
cur = coon.cursor()
# 3 执行sql
sql = "select * from goods;"
cur.execute(sql)
# 4 获取数据
data = cur.fetchall()
print(data) # 元组类型 元组中的每一个元素都是一个数据库总的数据
# 5.关闭
cur.close()
coon.close()
提交数据: conn.commit()
import pymysql
# 1 建立连接
conn = pymysql.connect(host='localhost', port=3306,user='root',password='mysql',database='jing_dong' charset='utf8')
# 2 创建游标 游标可以记录获取数据的个数
cur = coon.cursor()
# 3 执行sql
sql = "update goods set price=99 where id=1 ;"
cur.execute(sql)
# 4 获取数据
data = cur.fetchall()
print(data) # 元组类型 元组中的每一个元素都是一个数据库总的数据
# 只要对数据库进行增删改,都需要提交,否则不会修改
conn.commit()
# 5.关闭
cur.close()
coon.close()
sql注入
import pymysql
# 1 建立连接
conn = pymysql.connect(host='localhost', port=3306,user='root',password='mysql',database='jing_dong' charset='utf8')
# 2 创建游标 游标可以记录获取数据的个数
cur = coon.cursor()
# 3 执行sql
good_name = input('请输入要查询的物品名称:')
sql = "select * from goods where name='%s'"
# 给sql语句写参数的时候要在execute中写(防止sql注入)
cur.execute(sql,[good_name])
# 4 获取数据
data = cur.fetchall()
print(data) # 元组类型 元组中的每一个元素都是一个数据库总的数据
# 只要对数据库进行增删改,都需要提交,否则不会修改
conn.commit()
# 5.关闭
cur.close()
coon.close()
# 输入:or 1 or 会打印所有的数据
5.9 事务
概念:用户定义的一个数据库操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位
事务ACID:
- 原子性:事务是数据库的逻辑工作单位,事务中的操作要么全部做,要么全不做
- 一致性:是从一个一致性的状态转化为另一个一致性的状态,要么全部成功,要么全部失败
- 隔离性:一个事务的执行不能被其他事务干扰
- 持久性:对数据库的改变是永久的
使用:
1. 开始事务 begin 或者 start transaction
2. 提交事务 commit
3. 回滚事务 rollback
5.10 索引
介绍:特殊的文件 会保存着数据表里所有记录的位置信息
优点:加快查询的时间
缺点:创建和维护索引要消耗时间,占用物理空间
-- 查看表中已有的索引
show index from 表名;
-- 索引的创建
alter table 表名 add index 索引名[可选](列名,...)
alter table classes and index my_name (name);
-- 删除索引
drop index 索引名 on 表名;
6. 闭包和装饰器
6.1 深拷贝和浅拷贝
-
普通的赋值:a=b; 引用传递,a的地址和b的地址是一样的
-
浅拷贝:只会开辟一片空间
在没有嵌套的情况下是安全的,a和b的地址是不同的
嵌套情况下:不安全的
-
深拷贝:会把要拷贝的空间完全赋值一份,保证空间的独立性,都是安全的
-
拷贝不可变类型
- 不管是普通的赋值还是深拷贝和浅拷贝都不会开辟新的空间
- 不可变类型里嵌套了可变的类型
- 普通的赋值:是不安全的
- 浅拷贝:不安全的
- 深拷贝:安全的
5.python中的拷贝:大多数都是浅拷贝
6.2 闭包定义与使用
- 函数参数
# 函数名存放的是函数所在空间的地址
def func():
print('func')
# print(func)
# 去到函数所在的空间执行对应的代码
# func()
# 0x11
def my_test(func):
# 0x11()
func()
# 在python中参数产地传递的都是引用(地址)
# ox11
my_test(func)
-
定义:
-
条件
# 1 在函数嵌套的前提下 # 2 内部函数使用了外部变量 # 3 外部函数返回了内部函数
6.3 修改闭包内使用的外层函数变量
def func_out(data):
# 这个num1属于 func_out
num1 = 100
print('外层函数1:', num1)
def func_in():
# 这个num1属于func_in
# 就近原则
nonlocal num1
num1 = 1000
print('内部函数2:', num1)
# 执行func_in 这个时候num1变成了1000
func_in()
print('修改后的num1:', num1)
return func_in
func = func_out(10)
func()
6.4 装饰器
- 定义和流程
# 装饰器:在不修改原有函数代码的前提下 给函数增加新的功能
def func_out(func):
def func_in():
print('验证')
func()
return func_in
@func_out # login = func_out(login)
def login():
print('登录')
login()
#结果:
#验证
#登录
- 装饰器的使用
import time
# 计算程序运行的时间
def func_out(func):
def func_in():
start = time.time()
func()
end = time.time()
take_time = end -start
print('使用时间为:', take_time)
return func_in
# 被装饰的函数
@func_out
def my_test():
for i in range(100000):
print(i)
my_test()
- 装饰带有参数的函数
def func_out(func):
def func_in(a):
func(a)
return func_in
@func_out # my_test = func_out(my_test)
def my_test(a):
print(a)
my_test(10)
- 装饰带有返回值的函数
def func_out(func):
def func_in():
# 函数中如果没有return 证明函数是没有返回值的 默认返回None
ret = func()
return ret
return func_in
@func_out # my_test = func_out(my_test)
def my_test():
return 100
a = my_test()
print(a)
6.5 通用版本装饰器
def func_out(func):
def func_in(*args, **kwargs):
# 函数中如果没有return 证明函数是没有返回值的 默认返回None
ret = func(*args, **kwargs)
return ret
return func_in
@func_out # my_test = func_out(my_test)
def my_test():
return 100
a = my_test()
print(a)
6.6 多个装饰器
6.7 带有参数的装饰器
6.8 类装饰器
class Func:
def __init__(self, fn):
# fn就是用来保存原始的被装饰的函数的
self.__fn = fn
# 让我们对象() 就可以直接调用这个call方法
def __call__(self):
print("验证")
# 原始的被装饰的函数
self.__fn()
@Func # my_test = Func(my_test)
# a = Func(1)
def my_test():
print('登录')
my_test()
7. html和css基础
7.1 html介绍
超文本标记语言
7.2 html框架
<!-- 文档声明:html文件 html5版本 -->
<!DOCTYPE html>
<!-- 告诉浏览器 html代码从这里开始 lang="en"声明英语-->
<html lang="en">
<!-- 页头 属性的设置,引入css js 相关的资源 -->
<head>
<meta charset="UTF-8">
<!-- 移动端自适应 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 网页标题 -->
<title>Document</title>
</head>
<!-- 页身 -->
<body>
</body>
<!-- 告诉浏览器 html代码从这里结束-->
</html>
7.2 常见标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 双标签 -->
<!-- 字体标签 大小是从打到小的 -->
<h1>itcast</h1>
<h2>itcast</h2>
<h3>itcast</h3>
<!-- 段落标签 -->
<p>111111</p>
<p>111222</p>
<!-- 2 单标签 -->
<!-- 换行标签 -->
itcast
<br>
itcast1
<!-- 横线标签 -->
<hr>
<!-- 带有属性的标签 -->
<!-- 图片标签 -->
<img src="" alt="百度">
<br>
<!-- 链接标签 必须写http -->
<a href="http://www.baidu.com">百度</a>
<!-- 所有的双标签都可以嵌套 -->
<a href="http://www.baidu.com">
<img src="" alt="123">
</a>
</body>
</html>
7.3 列表和表格标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!--
有序列表标签(ol)
无序列表标签(ul)
列表(li标签)
-->
<!-- 有序列表标签(ol) -->
<ol>
<li>python</li>
<li>java</li>
<li>c++</li>
</ol>
<!-- 无序列表标签(ul) -->
<ul>
<li>python</li>
<li>java</li>
<li>c++</li>
</ul>
<!-- 表格标签 -->
<!--
table : 表格标签
属性
border="1px" style="border-collapse:collapse"
tr :表格行标签
th : 表格列标签
td : 表格数据标签
-->
<table border="1px" style="border-collapse:collapse">
<!-- 第一行 -->
<tr>
<th>name</th>
<th>age</th>
<th>sex</th>
</tr>
<!-- 第二行 -->
<tr>
<td>老王</td>
<td>18</td>
<td>男</td>
</tr>
<!-- 第三行 -->
<tr>
<td>老李</td>
<td>20</td>
<td>男</td>
</tr>
</table>
</body>
</html>
效果图
7.4 表单标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!--
form:表单标签
label:标记标签(通常和input标签一起使用)
input:输入标签
(type属性)
text-文本输入框
passWord - 密码输入框
radio - 单选框
checkbox - 复选框
file - 上传文件
submit - 提交按钮
reset - 重置按钮
(value 属性)
设定value值,用于网络间传输
(name 属性)
设定key值,用于网络传输
textarea:多行文本框
select:下拉框
option:选项框
-->
<form action="">
<p>
<label >姓名:</label>
<input type="text">
</p>
<p>
<label>密码:</label>
<input type="password">
</p>
<p>
<label>性别:</label>
<input type="radio">男
<input type="radio">女
</p>
<p>
<label>照片:</label>
<input type="checkbox">唱歌
<input type="checkbox">跑步
<input type="checkbox">游泳
</p>
<p>
<label>照片:</label>
<input type="file">
</p>
<p>
<label>个人描述:</label>
<textarea></textarea>
</p>
<p>
<label>籍贯:</label>
<select>
<option value="">北京</option>
<option value="">上海</option>
<option value="">深圳</option>
<option value="">广州</option>
</select>
</p>
<p>
<input type="submit" value="提交">
<input type="reset" value="重置">
</p>
</form>
</body>
</html>
7.5 表单提交
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!--
form表单中:
action属性 设置表单数据提交地址
method属性 设置表单提交的方式 一般有GET方式和POST方式,不区分大小写
表单标签中:
name属性 设置表单元素的名称,该名称是提交数据时的参数名
value属性 设置表单元素的值 该值是提交数据时参数名所对应的值
-->
<form action="http://192.168.144.36:8080" method="POST">
<p>
<label >姓名:</label>
<input type="text" name="name">
</p>
<p>
<label>密码:</label>
<input type="password" name="passwd">
</p>
<p>
<label>性别:</label>
<input type="radio" name="sex" value="1">男
<input type="radio" name="sex" value="0">女
</p>
<p>
<label>照片:</label>
<input type="checkbox" name="like" value="1">唱歌
<input type="checkbox" name="like" value="2">跑步
<input type="checkbox" name="like" value="2">游泳
</p>
<p>
<label>照片:</label>
<input type="file" name="pic">
</p>
<p>
<label>个人描述:</label>
<textarea name="desc"></textarea>
</p>
<p>
<label>籍贯:</label>
<select name="home">
<option value="1">北京</option>
<option value="2">上海</option>
<option value="3">深圳</option>
<option value="4">广州</option>
</select>
</p>
<p>
<input type="submit" value="提交">
<input type="reset" value="重置">
</p>
</form>
</body>
</html>
7.6 css导入方式
css 层叠样式表 美化
- 行内式 一行内使用
- 内嵌式 教学中
- 外链式 工作中css放在一个文件中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 内嵌式 -->
<style>
/* 在style里写代码 */
/* 作用于整个页面的而所有div标签的 */
/* div{
background: chartreuse;
} */
</style>
<!-- 外链式 link -->
<link rel="stylesheet" href="./css/main.css">
</head>
<body>
<!-- 行内式 只能在当前标签中使用,复用性差 基本不用 -->
<!-- <div style="width" >itcast</div>-->
<!-- 容器标签 -->
<div>itcast</div>
</body>
</html>
7.7 选择器
-
标签选择器
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> /* 1. 标签选择器 标签{ 属性:值 } 根据标签来选择标签,以标签开头,此种选择器影响的范围大,一般来做一些通用的设置 */ div{ background-color: blue; } p{ background-color: blue; } </style> </head> <body> <!-- 1 标签选择器 --> <div>123</div> <div>123</div> <div>123</div> <p>222</p> <p>222</p> <p>222</p> </body> </html>
-
类选择器
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> /* 1. 类选择器 需要给标签添加一个class属性 一个标签可以使用多个类,一个类选择器可以 可以用于多个标签 .类名{ 属性:值 } */ .box1{ background-color: blue; } .box2{ background-color: blue; } </style> </head> <body> <!-- 2 类选择器 --> <div class="box1">123</div> <div>123</div> <div>123</div> <p class="box2">222</p> <p>222</p> <p>222</p> </body> </html>
-
层级选择器
-
id选择器
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> /* 层级选择器(后代选择器)在标签嵌套中使用 选择器1和选择器2可以是任意的一种选择器 选择器1 选择器2{ 属性 = 值; } */ div p{ background-color: blue; } /* id选择器,在一个页面中,id是唯一的 id选择器只能作用于一个标签 不推荐使用 #id值{ 属性:值 } */ #box1{ background-color: blue; } #box2{ background-color: blue; } </style> </head> <body> <!-- 具有嵌套关系的标签 --> <div> <p> python </p> </div> <!-- 没有层级关系的标签 --> <p>pyhton</p> <!-- id选择器 --> <div id="box1">123</div> <div>123</div> <div>123</div> <p id="box2">222</p> <p>222</p> <p>222</p> </body> </html>
-
组选择器
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> /* 将多个选择器放在一起进行设置 选择器1,选择器2,选择器3...{ } */ /* 统一的设置 */ .box1,.box2,.box3{ height: 200px; width: 200px; } /* 每个标签单独设置 */ .box1{ background-color: blue; } .box2{ background-color: blueviolet; } .box3{ background-color: cyan; } </style> </head> <body> <div class="box1">1111</div> <div class="box2">2222</div> <div class="box3">3333</div> </body> </html>
-
伪类选择器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/* 伪类选择器 主要用在用户和网站的交互上,比如说:鼠标悬停,改变背景色
选择器:动作{
属性:值
}
*/
/* 使用标签选择器,对标签进行初始化处理 */
div{
height: 50px;
width: 50px;
background-color: darkblue;
}
/* 使用伪类选择器,做交互,鼠标放上去,改变背景色:hover */
div:hover{
height: 200px;
width: 200px;
background-color: darkred;
}
</style>
</head>
<body>
<div>python</div>
</body>
</html>
8. JavaScript
8.1 JS介绍
8.2 导入方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 内嵌式 使用script标签定义,写在head标签中 -->
<style>
input{
background-color: darkslategrey;
}
</style>
<script>
// js 弹窗函数
alert("你好")
</script>
<!--外链式 在外部定义js文件 使用script标签中的src属性链接-->
<script src="./js/main.js"></script>
</head>
<body>
<!-- 行内式,主要用于事件 -->
<input type="button" value="点击" onclick="alert('点一下')">
</body>
</html>
8.3 数据类型
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
// number 整数和小数
var iNum = 10;
// typeof()查看数据类型
typeof(iNum)
// 在控制台输出
console.log(iNum,typeof(iNum));
// float 小数
var fNum = 1.33;
// string字符串
var sStr = "123";
// null空对象-->object(null)
var nullData = null;
// object 对象类型
var oObj = {
age:18,
name:"老王"
};
// boollean
var isTrue = true;
// underfined 未定义类型
</script>
</head>
<body>
</body>
</html>
8.4 函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
// 函数的定义
function func(){
alert("函数定义");
};
// 函数调用
func();
// 定义带参数和返回值
function func2(num1,num2){
var iSum = num1 + num2;
alert(iSum);
return iSum;
};
var ret = func2(10,20);
alert("返回值"+ret);
// 作用域:
// 定义全局变量
var iNum = 100;
// 函数内部可以直接访问全局变量
function func2(){
console.log(iNum);
// 函数内部可以改变全局变量
// 函数外部不可以使用局部变量
iNum = 1000;
console.log(iNum)
}
</script>
</head>
<body>
</body>
</html>
8.5 条件判断
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
/* if else if else
if(判断条件1){
条件1成立执行的代码
} else if(判断条件2){
条件1不成立,条件2成立执行的代码
} else{
条件1和2都不成立,执行的代码
}
*/
// 输出成绩
var iNum=200;
if(iNum==100){
alert("成绩为100")
} else if(iNum==200){
alert("成绩为200")
} else{
alert("成绩不为100和200")
};
</script>
</head>
<body>
</body>
</html>
8.6 数组
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
// 1.数组定义
// 1.1使用new
var aList = new Array(1,2,3,4,5);
// 1.2使用字面量
var aList2 = [1,2,3,"123"]
// 2常用的方法
// 2.1求数组中数据的长度
console.log(aList.length);
// 2.2数组支持下标操作
console.log(aList[0]);
// 可以根据下标修改数组中的元素
aList[1] = "123";
console.log(aList[1]);
// 使用下标修改,如果下标值不存在,会在指定的下标添加这个数据,其他位置为空
// 2.3根据数据值,找这个数据值的下标,找到返回下标,没有找到返回 -1
console.log(aList.indexOf(3));
// 2.4尾部添加push和删除pop
aList.push(7);
aList.pop();
// 2.5任意位置添加和删除
// 数组.splice(start,num,elem,...elem)
// num 要删除的数据数量
// 后续参数要添加的数据
// 删除数据
aList.splice(2,3);
console.log(aList);
// 添加数据 num为0 从7开始插入8,9,10
aList.splice(7,0,8,9,10);
</script>
</head>
<body>
</body>
</html>
8.7 循环
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
// while循环 for循环 do..while循环
// 循环遍历一个数组
var aList = [1,2,3,4];
var iNum = 0;
while (iNum<aList.length) {
alert(aList[iNum]);
iNum++;
};
for(var iNum=0;iNum<aList.length;iNum++)
alert(aList[iNum]);
do{
alert("执行")
}while (2>3)
</script>
</head>
<body>
</body>
</html>
8.8 获取和设置标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
// 函数的定义写在外边,不要写在入口函数
function func(){
// 获取input标签中值
var oInput = document.getElementById("box1");
alert(oInput.value);
};
// 定义入口函数
window.onload = function(){
// 获取输入框标签
var oInput = document.getElementById("box1")
// 获取标签的value值
alert(oInput.value);
};
</script>
</head>
<body>
<input type="text" value="请输入姓名" id="box1">
<br>
<input type="button" value="按钮" id="box2" onclick="func()">
</body>
</html>
8.9 定时器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
var oT = null;
// 设置多次定时器
function fnClick(){
oT = setInterval(alert,2000,'好好学习');
};
// 取消
function fnStop(){
clearInterval(oT);
};
</script>
</head>
<body>
<p>单次定时器</p>
<input type="button" value="单词定时器" onclick="setTimeout(alert,3000,'hello')">
<p>多次定时器</p>
<input type="button" value="多次定时器" onclick="fnClick()">
<input type="button" value="停止" onclick="fnStop()">
</body>
</html>
8.10 JS对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
// 创建JS对象
// 1.new 创建
var oPerson = new Object();
// 添加属性
oPerson.name = '老王';
oPerson.age = 18;
// 添加方法
oPerson.func = function(){
alert("我是方法");
alert(this.name);
}
// 调用
oPerson.func();
// 2.s使用字面量
var oPerson = {
"name":"111",
"age":18,
func:function(){
alert(this.age);
}
};
</script>
</head>
<body>
</body>
</html>
8.11 json字符串
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
//定义一个json字符串
var sStr = '{"name":"小明","age":18,"like":["音乐","学习"]}';
console.log(typeof(sStr),sStr);
// json==>JS对象
var oObj = JSON.parse(sStr);
console.log(typeof(oObj),oObj0);
// 获取name属性和age属性
console.log(oObj.name,oObj.age);
// JS对象==>json字符串
var sStu = JSON.stringify(oObj);
console.log(typeof(sStu),sStu);
</script>
</head>
<body>
</body>
</html>
9. jQuery
9.1 介绍
9.2 JQuery用法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 导入 -->
<script src="./JS/jquery.js"></script>
<!-- 书写自己的JS或者jquery代码 -->
<script>
// 1 使用原生的JS 获取div标签
window.onloadf = function(){
var oDiv = document.getElementById("box1");
alert(oDiv.innerHTML);
};
// 2 使用jQuery
// $函数 函数调用为$()
// $(document) jquery 对象
//
// 2.1jQuery的入口函数
$(document).ready(function(){
$div = $("div");
alert($div.html());
});
// 2.2入口简写(使用最多)
// 页面加载完在执行函数
$(function(){
// 获取div标签
$div = $("div");
// 弹出div标签中的内容
alert($div.html());
});
</script>
</head>
<body>
<div id="box1">好好学习</div>
</body>
</html>
9.3 选择标签方式
- 选择器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 导入 -->
<script src="./JS/jquery.js"></script>
<!-- 书写自己的JS或者jquery代码 -->
<script>
// 对页面标签进行操作,需要将代码写在入口函数中
$(function(){
// 选择器标签选择成功,返回数组,可以使用length判断是否成功
// 1.标签选择器 $('标签名')
$div = $("div");
alert($div.length);
alert($div[1].innerHTML);
// 2.类选择器 $('.类名')
alert($('.box').html());
// 3.ID选择器 $('#ID名')
alert($('#box1').html());
// 4.层级选择器 $('选择器1 选择器2')
alert($('div p').html());
// 5.属性选择器
alert($("div[class='box']").html());
});
</script>
</head>
<body>
<div class="box">好好学习</div>
<div id="box1">天天向上</div>
<div>
<p name="123">
good good study!
</p>
</div>
</body>
</html>
- 选择集过滤
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./JS/jquery.js"></script>
<script>
$(function(){
// 使用标签选择器选择标签
$("div").css({'color':'blue'});
// has在选择器中进行筛选有子标签为p
$("div").has("p").css({"color":"red"});
// eq()下标 从0开始
$("div").eq(2).css({"color":"yellow"});
});
</script>
</head>
<body>
<div >第一个 好好学习</div>
<div >
第二个
<p>天天向上</p>
</div>
<div>
第三个 天天向上
</div>
</body>
</html>
- 选择集转移
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./JS/jquery.js"></script>
<script>
$(function(){
// 使用类选择器,选择3这个标签
$Li = $(".class_3");
// 选择这个标签前一个标签 prev()
$Li.prev().css({"color":"blue"});
// 选择这个标签前边所有的标签 prevALL()
$Li.prevALL().css({"color":"green"});
// 选择这个标签后边一个标签 next()
$Li.next().css({"color":"pink"});
// 选择这个标签后边所有标签 nextALL()
$Li.nextALL().css({"color":"orange"});
// 选择这个标签同一级别的标签 siblings()
$Li.siblings().css({"color":"pruple"});
// 选择这个标签父标签 parent()
$Li.parent().css({"color":"brown"});
// 孩子标签 children()
$("ul").children().css({"color":"blue"});
// find() 在子标签中查找满足,最终使用的是子标签
$("#id_div").find(".class_p").css({"color":"red"});
});
</script>
</head>
<body>
<ul>
<li>1</li>
<li>2</li>
<li class="class_3">3</li>
<li>4</li>
<li id="id_5">5</li>
<li>6</li>
<li>7</li>
<li>8</li>
</ul>
<br><hr>
<div id="id_div">
这是一个div
<p>好好学习</p>
<p class="class_p">天天向上</p>
<p>good good study</p>
这是一个div
</div>
</body>
</html>
9.4 获取和设置标签
-
内容
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="./JS/jquery.js"></script> <script> $(function(){ // 获取标签中的内容,html() 标签中的内容 alert($("div").eq(1).html()); // 设置标签找那个的内容 // alert($("div").eq(1).html("修改后的内容")); // 只需要文本内容 text() alert($("div").eq(1).text()); // 追加内容 append() $("div").eq(0).append('<a href="www.baidu.com">百度</a>'); }); </script> </head> <body> <div> 这是一个 div1. </div> <div id="box"> 这是一个div2 <a href="www.baidu.com">百度</a> </div> </body> </html>
-
属性
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="./JS/jquery.js"></script> <script> $(function(){ // 获取a标签属性 prop() alert($("a").prop("href")); // 修改标签的属性 $("a").prop({"href":"www.huya.com"}); // 获取input标签 // 获取和设置 value值,可以使用prop方法 // 获取value值的简单方法 alert($("input").val()); // 修改value值 $("input").val(200); }); </script> </head> <body> <p> <a href="www.baidu.com" style="width:200px">百度</a> </div> </p> <p> <input type="text" name="name" value="100"> </p> </body> </html>
9.5 事件
- 事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./JS/jquery.js"></script>
<script>
$(function(){
//1.click()
$("li").click(function(){
// $(this) 获取被点击的标签
$(this).css({"background":"red"});
});
// 一般和button结合使用 获取input标签中的内容
// 获取input标签内容
$("#btn").click(function(){
alert($("#input").val());
});
// 2 blur() 失去焦点(输入框)
$("#input").blur(function(){
$(this).css({"background":"red"});
})
// 3 focus() 获取焦点(输入框)
$("#input").focus(function(){
$(this).css({"background":"blue"});
})
// 4 mouseover() 鼠标进入
$("#input").mouseover(function(){
$(this).css({"background":"black"});
})
// 5 mouseout() 鼠标离开
$("#input").mouseout(function(){
$(this).css({"background":"yellow"});
})
});
</script>
</head>
<body>
<div class="box">
<ul>
<li>文字1</li>
<li>文字2</li>
<li>文字3</li>
</ul>
<p>
<input type="text" name="name" value="请输入" id="input">
</p>
<p>
<input type="button" value="提交" id="btn">
</p>
</div>
</body>
</html>
- 事件冒泡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./JS/jquery.js"></script>
<script>
// 阻止冒泡事件
$(function(){
$("div").click(function(event){
event.stopPropagation();
});
});
</script>
<script>
// 事件冒泡,子标签的事件会向父级标签进行传递
$(function(){
$("div").click(function(){
alert($(this).text());
});
});
</script>
</head>
<body>
<div class="box1">
我是 div1 标签
<div class="box2">
我是 div2 标签
</div>
</div>
</body>
</html>
- 事件代理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./JS/jquery.js"></script>
<script>
$(function(){
//对所有的li标签进行click事件,循环绑定的
// $("li").click(function(){
// // $(this) 获取被点击的标签
// $(this).css({"background":"red"});
// });
// 事件代理,父级标签做代理,设置标签,只绑定一次 delegate
$('ul').delegate('li','click',function(){
$(this).css({"background":"red"})
});
// 代码添加代码
$('ul').append('<li>文字4</li>');
$('ul').append('<li>文字5</li>');
});
</script>
</script>
</head>
<body>
<div class="box">
<ul>
<li>文字1</li>
<li>文字2</li>
<li>文字3</li>
</ul>
</div>
</body>
</html>