0. 杂七杂八
调用方法进行传参时,可以使用快捷键(ctrl + p)弹出提示,提示传入的参数是什么类型的
1. 类
1. 类的定义与使用
class 类名称:
类的属性(定义在类中的变量,成员变量)
类的行为(定义在类中的函数,成员方法)
对象 = 类名称() # 创建类对象
对象.成员变量 = xxx #给类对象的成员变量赋值
对象.成员方法() # 使用类对象的成员方法
注意在类中定义成员方法(函数)和不在类中定义函数是有区别的
类中定义的函数称为成员方法,不在类中定义的函数不能叫成员方法
定义函数格式上的区别
类中:
def 方法名(self, 形参1, 形参2, ...):
不在类中:
def 函数名(形参1, 形参2, ...):
相较于不在类中的定义,类中定义函数,会多一个
self
关键字,且必须写上
self
关键字用来表示类对象自身的意思,当使用类对象调用方法时,self
会自动被python传入,在成员方法内部,想要访问类的成员变量,必须使用self
def student(): name = None def say_hi(self, msg): print(f"hi大家好,我是{self.name}年龄是{msg}") #调用类中的成员变量时使用self关键字调用,调用其他参数时,按创建的对象传入的参数调用即可
调用方法传参时,
self
是透明的,不需要向self
传参
2. 内置方法
构造方法 __init__
__init__()
:python中的构造方法,可以实现
- 在创建类对象(构造类)的时候,会自动执行
__init__
方法 - 在创建类对象(构造类)的时候,将传入的参数自动传递给
__init__
方法使用
class student:
name = None
age = None
def __init__(self, name, age):
self.name = name
self.age = afg
student_1 = student("xxx", 20) # 在创建类对象的时候,直接传入参数,会调用__init__方法,直接赋值给类对象的成员变量
注意:
- 构造方法传入参数必须要有
self
关键字,以及其余成员变量
字符串方法 __str__
__str__()
:python中的字符串方法,可以实现
- 当没有字符串方法,类对象需要被转换为字符串时,则会输出类对象的内存地址
- 当有字符串方法,类对象需要被转换为字符串时,则会输出字符串方法内定义的输出结构
"""如果没有定义字符串方法"""
class Student:
name = None
age = None
address = None
def __init__(self, name, age, address):
self.name = name
self.age = age
self.address = address
student_1 = Student("name", 0, "address")
print(student_1) # <__main__.Student object at 0x000001E2019B75C8>
print(str(student_1)) # <__main__.Student object at 0x000001E2019B75C8>
"""如果定义了字符串方法"""
class Student:
name = None
age = None
address = None
def __init__(self, name, age, address):
self.name = name
self.age = age
self.address = address
def __str__(self):
return f"Student类对象的name={self.name},age={self.age},address={self.address}"
student_1 = Student("name", 0, "address")
print(student_1) # Student类对象的name=name,age=0,address=address
print(str(student_1)) # Student类对象的name=name,age=0,address=address
小于、大于符号比较方法 __lt__
__lt__()
:python中的小于、大于符号比较方法,可以实现
- 当没有定义小于、大于符号比较方法时,直接对两个类对象进行比较是不可以的
- 当定义小于、大于符号比较方法时,可以同时完成:小于符号和大于符号的比较
"""如果没有定义小于、大于符号比较方法"""
class Student:
name = None
age = None
address = None
def __init__(self, name, age, address):
self.name = name
self.age = age
self.address = address
student_1 = Student("name", 0, "address")
student_2 = Student("name", 1, "address")
print(student_1 < student_2) # TypeError: '<' not supported between instances of 'Student' and 'Student'
"""如果定义小于、大于符号比较方法"""
class Student:
name = None
age = None
address = None
def __init__(self, name, age, address):
self.name = name
self.age = age
self.address = address
def __lt__(self, other):
return self.age < other.age
student_1 = Student("name", 0, "address")
student_2 = Student("name", 1, "address")
print(student_1 < student_2) #True
小于等于、大于等于符号比较方法 __le__
__le__()
:python中的小于等于、大于等于符号比较方法,可以实现
- 当没有定义小于等于、大于等于符号比较方法时,直接对两个类对象进行比较是不可以的
- 当定义小于等于、大于等于符号比较方法时,可以同时完成:小于等于符号和大于等于符号的比较
"""如果没有定义小于等于、大于等于符号比较方法"""
class Student:
name = None
age = None
address = None
def __init__(self, name, age, address):
self.name = name
self.age = age
self.address = address
student_1 = Student("name", 0, "address")
student_2 = Student("name", 1, "address")
print(student_1 <= student_2) # TypeError: '<=' not supported between instances of 'Student' and 'Student'
"""如果定义小于等于、大于等于符号比较方法"""
class Student:
name = None
age = None
address = None
def __init__(self, name, age, address):
self.name = name
self.age = age
self.address = address
def __le__(self, other):
return self.age <= other.age
student_1 = Student("name", 0, "address")
student_2 = Student("name", 1, "address")
print(student_1 <= student_2) #True
==符号比较方法 __eq__
__eq__()
:python中的==符号比较方法,可以实现
- 当没有定义==符号比较方法时,无论比较的是什么,结果都返回
False
- 当定义==符号比较方法时,可以完成:等于符号的比较
"""如果没有定义==符号比较方法"""
class Student:
name = None
age = None
address = None
def __init__(self, name, age, address):
self.name = name
self.age = age
self.address = address
student_1 = Student("name", 0, "address")
student_2 = Student("name", 1, "address")
print(student_1 == student_2) # False
"""如果定义==符号比较方法"""
class Student:
name = None
age = None
address = None
def __init__(self, name, age, address):
self.name = name
self.age = age
self.address = address
def __eq__(self, other):
return self.age == other.age
student_1 = Student("name", 0, "address")
student_2 = Student("name", 1, "address")
print(student_1 == student_2) #False
注意
- 对于构造方法:
- 构造方法传入参数必须要有
self
关键字,以及其余成员变量 - 没有
return
- 构造方法传入参数必须要有
- 对于字符串方法、小于大于符号比较方法、小于等于大于等于符号比较方法、==符号比较方法:
- 传入参数只有
self
和other
,其中other
为另一个类对象 - 必须有
return
,且返回值为True
或False
- 传入参数只有
2. 面向对象
三大特征:封装、继承、多态
1. 封装
表示将现实世界事物的属性、行为封装到类中,描述为成员变量、成员方法,从而完成程序对现实世界事物的描述
属性和行为分为对用户开放的、对用户隐藏的,其中对用户隐藏的在类中称为私有成员变量和私有成员方法
私有成员变量、私有成员方法
为了在类中提供仅供内部使用的属性和方法,而不对类对象开放使用的属性和方法
- 私有成员变量和私有成员方法的定义:变量名或方法名以
__
开头(两个下划线) - 私有成员方法无法直接被类对象使用
- 私有成员变量无法被类对象赋值或获取值
- 私有成员变量和私有成员方法可以被类中其他的成员变量或成员方法访问
- 当类对象调用了调用了私有成员方法的成员方法时,会执行私有成员方法内的代码
class Mobile_phone:
__is_5g_single = True
def __check5g(self):
if self.__is_5g_single:
print("5g开启")
else:
print("5g关闭,使用4g网络")
def call_by_5g(self):
self.__check5g()
print("正在通话中")
mobile_phone = Mobile_phone()
mobile_phone.call_by_5g() # 5g开启 正在通话中
2. 继承
class 类名(父类名):
:子类会继承父类中所有非私有的成员变量和成员方法
继承分为:单继承和多继承
单继承
class 类名(父类名):
class Mobile_phone_4g:
__is_4g_single = True
def __check4g(self):
if self.__is_4g_single:
print("4g开启")
else:
print("4g关闭,使用3g网络")
def call_by_4g(self):
self.__check4g()
print("正在通话中")
class Mobile_phone_5g(Mobile_phone_4g):
__is_5g_single = True
def __check5g(self):
if self.__is_5g_single:
print("5g开启")
else:
print("5g关闭,使用4g网络")
def call_by_5g(self):
self.__check5g()
print("正在通话中")
mobile_phone_5g = Mobile_phone_5g()
mobile_phone_5g.call_by_4g() # 4g开启 正在通话中
mobile_phone_5g.call_by_5g() # 5g开启 正在通话中
多继承
class 类名(父类名1, 父类名1, 父类名3, ...):
注意
- 如果子类继承了多个父类,且子类无新增成员变量和成员方法,则类中只需要写
pass
即可- 如果多个父类中有同名的成员变量或成员方法,那么默认以继承顺序(从左到右)为优先级,先继承的保留,后继承的不保留
复写
当子类继承父类后,可以对其父类中的成员变量或成员方法进行复写,即在子类中重新定义同名的成员变量或成员方法即可
当复写成员变量或成员方法后:
- 类对象调用成员变量或成员方法时,会调用复写后的成员变量或成员方法
- 如果类对象想要调用复写前的成员变量或成员方法
- 方法1:调用父类成员变量或成员方法
- 使用成员变量:
父类名.成员变量
- 使用成员方法:
父类名.成员方法(self)
- 使用成员变量:
- 方法2:使用
super()
- 使用成员变量:
super().成员变量
- 使用成员方法:
super().成员方法()
,注意这里没有self
关键字
- 使用成员变量:
- 方法1:调用父类成员变量或成员方法
3. 多态
指的是多种状态,即完成某个行为时,使用不同的对象会得到不同的状态
同样的行为(函数),传入不同的对象,得到不同的状态
多态常作用在继承关系上
比如:
- 函数(方法)形参声明接收父类对象
- 实际传入父类的子类对象进行工作
- 即:
- 以父类做定义声明
- 以子类做实际工作
- 用以获取同一行为的不同状态
- 定义一个父类
- 定义多个子类继承父类,并重写父类的某一成员方法
- 定义一个函数,形参声明使用父类,使用父类被复写的成员方法
- 创建多个不同的子类对象
- 调用函数,传入不同的子类对象,此时函数调用的父类中被复写的成员方法被子类中的复写的成员方法覆盖
- 实现多态
抽象类(接口)
定义一个抽象类,在抽象类中只声明有什么方法,并不写具体的方法实现,子类自行实现方法的具体实现
抽象类:含有抽象方法的类
抽象方法:方法体是空实现的(pass
)
class Animal:
def eat(self):
pass
def drink(self):
pass
class Dog(Animal):
def eat(self):
print("狗吃饭")
def drink(self):
print("狗喝水")
class Cat(Animal):
def eat(self):
print("猫吃饭")
def drink(self):
print("猫喝水")
def Drink(animal: Animal):
animal.drink()
def Eat(animal: Animal):
animal.eat()
dog: Dog = Dog()
cat: Cat = Cat()
drink_dog: Dog = Dog()
Drink(drink_dog)
drink_cat: Cat = Cat()
Drink(drink_cat)
eat_dog: Dog = Dog()
Eat(eat_dog)
eat_cat: Cat = Cat()
Eat(eat_cat)
4. 类型注解
当PyCharm无法通过代码确定应传入什么类型的参数,此时需要使用类型注解,在代码中涉及数据交互的地方,提供数据类型的注解(显式的说明)
主要功能:
- 帮助第三方IDE工具(如PyCharm)对代码进行类型推断,协助做代码提示
- 帮助开发者自身对变量进行类型注释
注意:类型注解只是程序的一个备注,并不会影响程序的运行
变量的类型注解
方法1:变量: 类型
# 基础数据类型注解
变量: 基础数据类型 = 变量值
# 类对象类型注解
类对象: 类名类型 = 类名()
# 基础容器类型注解
变量: 基础容器类型 = 值
# 基础类型详细注解
变量: 基础容器类型[容器内变量的基础数据类型] = 值
my_tuple: tuple[str, int, bool, ...] = ("name", 0, True, ...) # 元组类型设置类型详细注解是,需要将每一个元素的基础数据类型都标记出来
my_dict: dict[str, int] = ["name": 0] # 字典类型设置类型详细注解时,需要两个类型,第一个是key,第二个是value
方法2:# type: 类型
函数(方法)的类型注解
- 为函数(方法)的形参进行类型注解
def 函数(方法)名(形参1: 类型, 形参2: 类型, ...):
- 为函数(方法)的返回值进行类型注解
def 函数(方法)名(形参1: 类型, 形参2: 类型, ...) -> 返回值类型:
Union类型
存放或使用的元素类型有多种并不好用变量的类型注解或者函数(方法)的类型注解进行标记时,可以使用Union[基础数据类型1, 基础数据类型2, ..]
进行联合注解,即存放的元素可以为联合注解中带有的基础数据类型的任意一种
3. SQL
1. DDL
数据库的创建删除、表的创建删除
SHOW DATABAS
:查看数据库USE 数据库名称
:使用数据库CREATE DATABASE 数据库名称
:创建数据库DROP DATABASE 数据库名称
:删除数据库SELECT DATABASE()
:查看当前使用的数据库SHOW TABLES
:查看当前库中的表DROP TABLE 表名称
:删除表DROP TABLE IF EXISTS 表名称
:删除表CREATE TABLE 表名称( 列名称 列类型, 列名称 列类型, ...)
2. DML
对表中的数据记录进行插入、删除、更新
INSERT INTO 表名 [(列1, 列2, ...)] VALUES (值1, 值2, ...), (值1, 值2, ...), ...
DELECT FROM 表名 [WHERE 条件判断]
UPDATE 表名 SET 列=值 [WHERE 条件判断]
3. DQL
- 对数据进行查询
SELECT 字段列表|* FROM 表
SELECT 字段列表|* FROM 表 WHERE 条件判断
- 分组聚合
- 根据列进行分组查询
SELECT 字段|聚合函数 FROM 表 [WHERE 条件] GROUP BY 列
- 聚合函数:
SUM(列)
:求和AVG(列)
:求均值MIN(列)
:求最小值MAX(列)
:求最大值COUNT(列|*)
:求数量
- 注意:在
GROUP BY
中出现了哪个列,哪个列才能在SELECT
中的非聚合中
- 聚合函数:
- 结果排序
- 对查询结果进行排序分页
SELECT 列|聚合函数|* FROM 表 [WHERE ...] [GROUP BY ...] ORDER BY ... [ASC|DESC] [LIMIT n[ ,m]]
ASC
:升序DESC
:降序3n
:限制只查询n
条数据n, m
:限制只查询从第n
条数据开始,总共m
条数据
DQL执行顺序:
FROM>WHERE>GROUP BY和聚合函数>SELECT>ORDER BY>LIMIT
4. Python&MySQL
from pymysql import Connection
# 获取到MYSQL数据库的连接对象
conn = Connection(
host='localhost', # 主机名或IP地址
port=3306, # 端口号,默认3306
user='root', # 账户名
password='xxx', # 密码
autocommit=True # 设置自动提交数据库,此时就不需要在执行完增加、删除、修改语句后使用连接对象.commit()语句了
)
# 打印MYSQL数据软件信息
print(conn.get_server_info())
# 执行非查询语句
"""
获取游标对象
选择相应数据库
使用游标对象,执行sql语句
"""
cursor = conn.cursor() # 获取游标对象
conn.select_db("db1") # 选择相应数据库
# cursor.execute("CREATE TABLE test_pymysql(id INT, name VARCHAR(10) )") # 使用游标对象,执行sql语句
cursor.execute("INSERT INTO test_pymysql VALUE (11, 'AbleLynn')") # 使用游标对象,执行插入、删除、修改语句
conn.commit() # 当执行插入、删除、修改语句,需要连接对象.commit()语句提交数据库
# 执行查询语句
"""
获取游标对象
选择相应数据库
使用游标对象,执行sql语句
获取查询结果
"""
# cursor = conn.cursor() # 获取游标对象
# conn.select_db("db1") # 选择相应数据库
# cursor.execute("SELECT * FROM student") # 使用游标对象,执行sql语句
# result: tuple = cursor.fetchall() # 获取查询结果
# for r in result:
# print(r)
# 关闭数据库连接
conn.close()
注意编写sql语句时,数据类型,有些数据需要加单引号