Python学习打卡:day17

day17

笔记来源于:黑马程序员python教程,8天python从入门到精通,学python看这套就够了

目录

121、Python 操作 MySQL 基础使用

pymysql

在Python中,使用第三方库:pymysql 来完成对MySQL数据库的操作。

安装:

1、pip install pymysql;

2、或者 PyCharm中安装包 PyMySQL(使用清华源:https://pypi.tuna.tsinghua.edu.cn/simple)。

创建到 MySQL 的数据库链接

python 复制代码
"""
演示 Python pymysql库的基础操作
"""
from pymysql import Connection

# 构建到 MySQL数据库的链接
conn = Connection(
    host = "localhost",     # 主机名(IP)
    port = 3306,            # 端口
    user= 'root',           # 账户
    password= '666666'      # 密码
)

# 打印 MySQL 数据库软件信息
# 验证是否连接上指定数据库
print(conn.get_server_info())

# 关闭链接
conn.close()

执行 SQL 语句

执行非查询性质的SQL语句

示例代码如下:

python 复制代码
"""
演示 Python pymysql库的基础操作
"""
from pymysql import Connection

# 构建到 MySQL数据库的链接
conn = Connection(
    host = "localhost",     # 主机名(IP)
    port = 3306,            # 端口
    user= 'root',           # 账户
    password= '666666'      # 密码
)

# # 打印 MySQL 数据库软件信息
# # 验证是否连接上指定数据库
# print(conn.get_server_info())

# 执行非查询性质的 SQL
cursor = conn.cursor()      # 获取到游标对象

# 选择数据库
conn.select_db("test")
# 执行 sql
cursor.execute("create table test_pymysql (id int);")

# 关闭链接
conn.close()
执行查询性质的SQL语句
python 复制代码
"""
演示 Python pymysql库的基础操作
"""
from pymysql import Connection

# 构建到 MySQL数据库的链接
conn = Connection(
    host = "localhost",     # 主机名(IP)
    port = 3306,            # 端口
    user= 'root',           # 账户
    password= '666666'      # 密码
)

# print(conn.get_server_info())

# 执行非查询性质的 SQL
# 获取到游标对象
cursor = conn.cursor()      

# # 选择数据库
# conn.select_db("test")
# # 执行 sql
# cursor.execute("create table test_pymysql (id int);")

# 选择数据库
conn.select_db("world")
# 使用游标对象,执行 sql 语句
cursor.execute("select * from student_1")
# 获取查询结果
results = cursor.fetchall()
for r in results:
    print(r)

# 关闭链接
conn.close()

122、Python 操作 MySQL 数据的插入

直接使用:

python 复制代码
cursor.execute("insert into student_2 values(10002, '林俊杰', 31, '男')")

经过执行是无法将数据插入到数据表 student 中的。

因为:pymysql在执行数据插入或其它产生数据更改的SQL语句时,默认是需要提交更改的,即,需要通过代码"确认"这种更改行为。通过链接对象.commit() 即可确认此行为。

示例代码:

python 复制代码
"""
演示使用 pymysql 库进行数据插入的操作
"""
from pymysql import Connection

# 构建到 MySQL数据库的链接
conn = Connection(
    host = "localhost",     # 主机名(IP)
    port = 3306,            # 端口
    user= 'root',           # 账户
    password= '666666',      # 密码
)

# 执行非查询性质的 SQL
cursor = conn.cursor()      # 获取到游标对象

# 选择数据库
conn.select_db("world")
# 执行 sql
cursor.execute("insert into student_2 values(10002, '林俊杰', 31, '男')")

# 通过 commit 确认
conn.commit()

# 关闭链接
conn.close()

自动 commit

如果不想手动commit确认,可以在构建链接对象的时候,设置自动commit的属性。

示例代码:

python 复制代码
# 构建到 MySQL数据库的链接
conn = Connection(
    host = "localhost",     # 主机名(IP)
    port = 3306,            # 端口
    user= 'root',           # 账户
    password= '666666',      # 密码
    autocommit=True         # 自动提交(确认)
)

123、综合案例

案例需求

我们使用《面向对象》章节案例中的数据集,完成使用Python语言,读取数据,并将数据写入MySQL的功能。

DDL 定义

本次需求开发我们需要新建一个数据库来使用,数据库名称:py_sql

基于数据结构,可以得到建表语句:

mysql 复制代码
create table orders(
order_date date,
order_id varchar(255),
money int,
province varchar(10)
);

实现步骤

示例代码:

DBeaver:

mysql 复制代码
create database py_sql charset utf8;

use py_sql;

create table orders(
order_date date,
order_id varchar(255),
money int,
province varchar(10)
);

Python:

python 复制代码
"""
SQL 综合案例,读取文件,写入 MySQL 数据库中
"""

from file_define import TextFileReader, JsonFileReader
from data_define import Record
from pymysql import Connection

text_file_reader = TextFileReader("E:/3code/PyCharm/pythonProject/mysql/03_综合案例/2011年1月销售数据.txt")
json_file_reader = JsonFileReader("E:/3code/PyCharm/pythonProject/mysql/03_综合案例/2011年2月销售数据JSON.txt")

jan_data: list[Record] = text_file_reader.read_data()
feb_data: list[Record] = json_file_reader.read_data()

# 将 2 个月份的数据合并为 1 个 list 来存储
all_data: list[Record] = jan_data + feb_data
print(all_data)

# 构建 MySQL 链接对象
conn = Connection(
    host='localhost',
    port=3306,
    user='root',
    password='666666',
    autocommit=True
)

# 获得游标对象
cursor = conn.cursor()

# 选择数据库
conn.select_db("py_sql")

# 组织 SQL 语句
for record in all_data:
    sql = (f"insert into orders(order_date, order_id, money, province) " 
           f"values('{record.date}', '{record.order_id}', '{record.money}', '{record.province}')")
    # print(sql)

    # 执行 SQL 语句
    cursor.execute(sql)

# 关闭 MySQL 链接对象

Python 高阶技巧

1、闭包

基础概念

通过全局变量account_amount来记录余额

尽管功能实现是ok的,但是仍有问题:

  • 代码在命名空间上(变量定义)不够干净、整洁
  • 全局变量有被修改的风险

因此:

  • 将变量定义在函数内部是行不通
  • 我们需要使用闭包

在函数嵌套的前提下,内部函数使用了外部函数的变量,并且外部函数返回了内部函数,我们把这个使用外部函数变量的内部函数称为闭包

简单闭包

示例代码:

python 复制代码
# 简单闭包
def outer(logo):

    def inner(msg):
        print(f"<{logo}>{msg}<{logo}>")
    return inner

fn1 = outer("黑马程序员")
fn1("welcome")

修改外部函数变量的值

示例代码:

python 复制代码
# 使用 nonlocal 关键字修改外部函数的值
def outer(num1):

    def inner(num2):
        nonlocal num1
        num1 += num2
        print(num1)
    return inner

fn = outer(10)
fn(10)
fn(20)
fn(20)
fn(20)

使用闭包实现 ATM 小案例

python 复制代码
"""
演示 Python 的闭包特性
"""
# 使用闭包实现 ATM 小案例
def account_create(initial_account = 0):
    def atm(num, deposit=True):
        nonlocal initial_account
        if deposit:
            initial_account += num
            print(f"存款, +{num}, 账户余额:{initial_account}")
        else:
            initial_account -= num
            print(f"存款, -{num}, 账户余额:{initial_account}")

    return atm

atm = account_create()

atm(100)
atm(200)
atm(100, deposit=False)

tips:

优点,使用闭包可以让我们得到:

  • 无需定义全局变量即可实现通过函数,持续的访问、修改某个值
  • 闭包使用的变量的所用于在函数内,难以被错误的调用修改

缺点:

  • 由于内部函数持续引用外部函数的值,所以会导致这一部分内存空间不被释放,一直占用内存

2、装饰器

装饰器其实也是一种闭包, 其功能就是在不破坏目标函数原有的代码和功能的前提下,为目标函数增加新功能。

装饰器的一般写法(闭包写法)

示例代码:

python 复制代码
# 装饰器的一般写法(闭包)
def outer(func):
    def inner():
        print("我睡觉了")
        func()
        print("我起床了")
    return inner

def sleep():
    import random
    import time
    print("睡眠中......")
    time.sleep(random.randint(1, 5))

fn = outer(sleep)
fn()

定义一个闭包函数, 在闭包函数内部:

  • 执行目标函数
  • 并完成功能的添加

执行结果:

python 复制代码
# 结果
我睡觉了
睡眠中......
我起床了

装饰器的语法糖写法

python 复制代码
def outer(func):
    def inner():
        print("我睡觉了")
        func()
        print("我起床了")
    return inner

@outer
def sleep():
    import random
    import time
    print("睡眠中......")
    time.sleep(random.randint(1, 5))

sleep()

使用@outer

定义在目标函数sleep之上

执行结果:

python 复制代码
# 结果
我睡觉了
睡眠中......
我起床了

3、单例模式

某些场景下, 我们需要一个类无论获取多少次类对象,都仅仅提供一个具体的实例,用以节省创建类对象的开销和内存开销,比如某些工具类,仅需要1个实例,即可在各处使用。

这就是单例模式所要实现的效果。

单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。

在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。

  • 定义:保证一个类只有一个实例,并提供一个访问它的全局访问点;
  • 适用场景:当一个类只能有一个实例,而客户可以从一个众所周知的访问点访问它时。

单例的实现模式:

4、工厂模式

当需要大量创建一个类的实例的时候, 可以使用工厂模式。

即,从原生的使用类的构造去创建对象的形式迁移到,基于工厂提供的方法去创建对象的形式。

例如:由

转到

上述示例使用工厂类的get_person()方法去创建具体的类对象

优点:

  • 大批量创建对象的时候有统一的入口,易于代码维护;
  • 当发生修改,仅修改工厂类的创建方法即可;
  • 符合现实世界的模式,即由工厂来制作产品(对象)。

示例代码:

python 复制代码
"""
演示 设计模式之工厂模式
"""
class Person:
    pass

class Worker(Person):
    pass

class Student(Person):
    pass

class Teacher(Person):
    pass

class PersonFactory:
    def get_person(self, p_type):
        if p_type == 'w':
            return Worker()
        elif p_type == 's':
            return Student()
        else:
            return Teacher()

pf = PersonFactory()
worker = pf.get_person('w')
stu = pf.get_person('s')
teacher = pf.get_person('t')

5、多线程并行执行概念

进程、线程

进程: 就是一个程序,运行在系统之上,那么便称之这个程序为一个运行进程,并分配进程ID方便系统管理。

线程:线程是归属于进程的,一个进程可以开启多个线程,执行不同的工作,是进程的实际工作最小单位。

进程就好比一家公司,是操作系统对程序进行运行管理的单位;

线程就好比公司的员工,进程可以有多个线程(员工),是进程实际的工作者。

操作系统中可以运行多个进程,即多任务运行;

一个进程内可以运行多个线程,即多线程运行。

tips:

进程之间是内存隔离的, 即不同的进程拥有各自的内存空间。 这就类似于不同的公司拥有不同的办公场所。

线程之间是内存共享的,线程是属于进程的,一个进程内的多个线程之间是共享这个进程所拥有的内存空间的。

这就好比,公司员工之间是共享公司的办公场所。

并行执行

并行执行的意思指的是同一时间做不同的工作。

进程之间就是并行执行的,操作系统可以同时运行好多程序,这些程序都是在并行执行。

除了进程外,线程其实也是可以并行执行的。

也就是比如一个Python程序,其实是完全可以做到:

  • 一个线程在输出:你好
  • 一个线程在输出:Hello

像这样一个程序在同一时间做两件乃至多件不同的事情, 我们就称之为:多线程并行执行

6、多线程编程

基本语法:

单线程:

示例代码:

python 复制代码
"""
演示 多线程编程的使用
"""

import time

def sing():
    while True:
        print("我在唱歌,啦啦啦...")
        time.sleep(1)

def dance():
    while True:
        print("我在跳舞,呱呱呱...")
        time.sleep(1)


if __name__ == '__main__':
    sing()
    dance()

# 结果
我在唱歌,啦啦啦...
我在唱歌,啦啦啦...
我在唱歌,啦啦啦...
我在唱歌,啦啦啦...
我在唱歌,啦啦啦...
我在唱歌,啦啦啦...
我在唱歌,啦啦啦...
我在唱歌,啦啦啦...
我在唱歌,啦啦啦...
我在唱歌,啦啦啦...
我在唱歌,啦啦啦...

单方面循环 sing()

多线程:

python 复制代码
"""
演示 多线程编程的使用
"""

import time
import threading

def sing():
    while True:
        print("我在唱歌,啦啦啦...")
        time.sleep(1)

def dance():
    while True:
        print("我在跳舞,呱呱呱...")
        time.sleep(1)

if __name__ == '__main__':
    # 创建一个唱歌线程
    sing_thread = threading.Thread(target=sing)
    
    # 创建一个跳舞线程
    dance_thread = threading.Thread(target=dance)
    
    # 进程启动
    sing_thread.start()
    dance_thread.start()
   
# 结果
我在唱歌,啦啦啦...
我在跳舞,呱呱呱...
我在唱歌,啦啦啦...我在跳舞,呱呱呱...

我在唱歌,啦啦啦...我在跳舞,呱呱呱...

我在跳舞,呱呱呱...
我在唱歌,啦啦啦...

多线程传参:

需要传参的话可以通过:

  • args参数通过元组(按参数顺序)的方式传参
  • 或使用kwargs参数用字典的形式传参

示例代码:

python 复制代码
"""
演示 多线程编程的使用
"""

import time
import threading

def sing(msg):
    while True:
        print(msg)
        time.sleep(1)

def dance(msg):
    while True:
        print(msg)
        time.sleep(1)

if __name__ == '__main__':
    # 创建一个唱歌线程
    sing_thread = threading.Thread(target=sing, args=("我要唱歌,哈哈哈",))
    
    # 创建一个跳舞线程
    dance_thread = threading.Thread(target=dance, kwargs={"msg":"我在跳舞,啦啦啦"})
    
    # 进程启动
    sing_thread.start()
    dance_thread.start()
    
# 结果
我要唱歌,哈哈哈
我在跳舞,啦啦啦
我要唱歌,哈哈哈
我在跳舞,啦啦啦
我要唱歌,哈哈哈
我在跳舞,啦啦啦
我在跳舞,啦啦啦
我要唱歌,哈哈哈
我在跳舞,啦啦啦
我要唱歌,哈哈哈
我要唱歌,哈哈哈我在跳舞,啦啦啦

我在跳舞,啦啦啦
我要唱歌,哈哈哈
我在跳舞,啦啦啦我要唱歌,哈哈哈
相关推荐
ka2x几秒前
订单折扣金额分摊算法|代金券分摊|收银系统|积分分摊|分摊|精度问题|按比例分配|钱分摊|钱分配
java·c语言·c++·python·算法·spring·spring cloud
爱上电路设计4 小时前
有趣的算法
开发语言·c++·算法
studyForMokey4 小时前
kotlin 函数类型接口lambda写法
android·开发语言·kotlin
2401_858120264 小时前
探索sklearn文本向量化:从词袋到深度学习的转变
开发语言·python·机器学习
与墨学长5 小时前
Rust破界:前端革新与Vite重构的深度透视(中)
开发语言·前端·rust·前端框架·wasm
虫小宝6 小时前
Java中的软件架构重构与升级策略
java·开发语言·重构
helloKittywz6 小时前
内网学习第6天 liunx定时任务 环境变量和权限配置,以及数据库提权
学习·web安全·网络安全·内网渗透·liunx·权限提升·学习记录
bigbearxyz6 小时前
Java实现图片的垂直方向拼接
java·windows·python
CTGU_daffodil6 小时前
matlab 绘制高等数学中的二维函数示例
开发语言·matlab
立秋67896 小时前
使用Python绘制堆积柱形图
开发语言·python