Python Web编程笔记

Python Web编程笔记

1 .多任务编程—进程

1.1 多任务介绍

​ 多任务:在同一时间内执行多个任务

​ 目的:充分利用CPU资源,提高程序的执行效率

并发:

​ 在一段时间内交替去执行多个任务(只有一个CPU)
并行:

​ 在同一时刻执行多个任务(多核CPU)

1.2 进程

​ 进程:在运行的程序

​ 进程:操作系统分配资源的最小单位

​ 线程:执行利用资源的基本单位

1.3 多进程的使用流程
  1. 导入模块(multiprocessing)

  2. 创建子进程(Process)

  3. 开启子进程(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. 每个进程都有自己的独立空间,进程之间无共享全局变量

  2. 结论:主进程默认会等待子进程结束之后再结束

    让子进程随着主进程的结束而结束

    (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 多线程的使用
  1. 导入模块(threading)

  2. 创建子进程(Thread)

  3. 开启子进程(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. 线程之间的执行是无序的

  2. 主线程会等待子线程的结束而结束

    设置守护进程

    (1)Thread(deamon = True)

    my_func = threading.Thread(target=func, daemon=True)
    

    (2) setDaemon

    my_func.setDaemon(True)
    
  3. 线程共享全局变量

​ 由于线程依附于进程,一个进程的所有的线程都是使用的同一片内存空间

​ 所以:一个进程的线程是共享全局变量的

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. 互斥锁

    对共享的数据进行锁定,保证同一时刻只能有一个线程去操作

    互斥锁的使用

    # 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地址

在网络中表示唯一一台设备

  1. 查看ip地址:

    ​ win: ipconfig

    mac和linux: ifconfig

  2. 测试网络是否畅通:

    ping IP地址

  3. 本机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客户端程序开发

基本流程

  1. 创建客户端套接字对象
  2. 和服务器套接字建立连接
  3. 发送数据
  4. 接受数据
  5. 关闭客户端套接字

编解码

​ 网络中必须传输二进制的数据

​ 字符串转化为二进制 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服务端开发

基本流程

  1. 创建服务端端套接字对象
  2. 绑定端口号
  3. 设置监听
  4. 等待接受客户端的连接请求
  5. 接受数据
  6. 发送数据
  7. 关闭套接字

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协议规定的就是sendrecv 接受和发送数据的具体格式

在这里插入图片描述

4.2 url

统一资源定位符:URL

组成:例如:https://news.163.com/18/1122.html

  1. 协议部分:https:// http:// ftp://
  2. 域名部分:news.163.com
  3. 资源路径部分:/18/1122.html
4.3 http协议的通信过程

4.4 HTTP请求报文

发送数据:请求报文

回复数据:应答报文

请求报文方式:

  1. GET方式:获取web服务器数据,只向服务器要数据,不给服务器提供数据

  2. 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 数据库

分类:关系型数据库、非关系型数据库

本质上:一种特殊的文件

数据库指的实际上是一个很多功能的整体:

  1. 数据库是由数据表组成的
  2. 数据表是用来存储数据的
  3. 存储一类相同信息的一列:字段
  4. 存储某个人活着事务详细信息的一行:记录
  5. 能够标识唯一一行记录的字段:主键(不能为空,不可重复)
  6. 表和表之间具有一定的关联的数据:关系型数据库

特点:持久化存储、读写速度极高、保证数据的有效性

关系型数据库管理系统:RDBMS

5.2 MySQL数据类型和约束

数据类型

  1. 整数:int,bit
  2. 小数:decimal
  3. 字符串:varchar ,char
  4. 日期时间:date,time,datetime
  5. 枚举类型: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 表名 set1=1,2=2... where 条件;

-- 查询基本使用
-- 查询所有列
select * from 表名;
-- 定条件查询
select * from 表名 where 条件;
-- 查询指定列
select1,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);

连接查询:将多张表连接成一个大的数据集进行汇总显示

  1. 内连接: 两个表的交集 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;
    
    
  2. 外连接:

    1. 左外连接:交集和左边表特有的数据(左边的表为主表和两个表的交集)

    2. 右外连接:交集和右边表特有的数据(右边的表为主表和两个表的交集)

      -- 左连接:主表 left join 从表 on 连接条件
      -- 右连接:从表 right join 主表 on 连接条件
      -- 查询 没有能够对应班级的学生
      select * from students left join classes on
      students.cls_id=classes.id where classes.name is NUll;
      
  3. 自连接:只需要使用一个表,可以加开查询速度,减少数据表占用空间

    -- 把一张表假设为两张一样的表,然后再做多表查询
    -- 将areas表取两个别名
    -- 连接的表按照条件 进行内连接
    -- 查找出需要的字段
    select city* from
    areas as city
    inner join
    areas as province 
    on city.id=province.aid
    where province.atitle='广东省';
    

在这里插入图片描述

5.7 数据库设计的三范式

范式:数据库合理性的规范

  1. 第一范式:字段不能再分,列不能再分,原子性
  2. 第二范式:满足1NF,表必须有主键;非主键字段 必须完全依赖于主键 不能出现部分从属(数据冗余)
  3. 第三范式:满足2NF,非主键必须直接依赖于主键,不能存在传递依赖(数据冗余)

E-R模型:描述数据库存储数据的结构模型

  1. 实体:矩形
  2. 属性:椭圆形
  3. 关系:菱形 (一对一,一对多,多对多)
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. 原子性:事务是数据库的逻辑工作单位,事务中的操作要么全部做,要么全不做
  2. 一致性:是从一个一致性的状态转化为另一个一致性的状态,要么全部成功,要么全部失败
  3. 隔离性:一个事务的执行不能被其他事务干扰
  4. 持久性:对数据库的改变是永久的

使用:

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 深拷贝和浅拷贝
  1. 普通的赋值:a=b; 引用传递,a的地址和b的地址是一样的

  2. 浅拷贝:只会开辟一片空间

    在没有嵌套的情况下是安全的,a和b的地址是不同的
    在这里插入图片描述

​ 嵌套情况下:不安全的

在这里插入图片描述

  1. 深拷贝:会把要拷贝的空间完全赋值一份,保证空间的独立性,都是安全的

  2. 拷贝不可变类型

    1. 不管是普通的赋值还是深拷贝和浅拷贝都不会开辟新的空间
    2. 不可变类型里嵌套了可变的类型
      1. 普通的赋值:是不安全的
      2. 浅拷贝:不安全的
      3. 深拷贝:安全的

5.python中的拷贝:大多数都是浅拷贝

6.2 闭包定义与使用
  1. 函数参数
# 函数名存放的是函数所在空间的地址
def func():
	print('func')
    
    
# print(func)
# 去到函数所在的空间执行对应的代码
# func()
# 0x11
def my_test(func):
	# 0x11()
    func()
    
# 在python中参数产地传递的都是引用(地址)
# ox11
my_test(func)
  1. 定义:
    在这里插入图片描述

  2. 条件

    # 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 装饰器
  1. 定义和流程

# 装饰器:在不修改原有函数代码的前提下 给函数增加新的功能
def func_out(func):
    def func_in():
        print('验证')
        func()

    return func_in


@func_out  # login = func_out(login)
def login():
    print('登录')


login()


#结果:
#验证
#登录

  1. 装饰器的使用
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()

  1. 装饰带有参数的函数
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)
  1. 装饰带有返回值的函数
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 层叠样式表 美化

  1. 行内式 一行内使用
  2. 内嵌式 教学中
  3. 外链式 工作中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 选择器
  1. 标签选择器

    <!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>
    

在这里插入图片描述

  1. 类选择器

    <!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>
    
  2. 层级选择器

  3. 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>
    
  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>
        
        <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>
    
  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>
    <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 选择标签方式
  1. 选择器
<!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>

  1. 选择集过滤
<!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>

  1. 选择集转移
<!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 获取和设置标签
  1. 内容

    <!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>
    
    
  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 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 事件
  1. 事件
<!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>

  1. 事件冒泡
<!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>

  1. 事件代理
<!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>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值