Python学习总结——②

第二章 强化

一、对象

1. 类的定义和使用

① 语法:

  • class 是关键字,表示要定义类了

  • 类的属性,即定义在类中的变量(成员变量)

  • 类的行为,即定义在类中的函数(成员方法)

# 创建类的语法
class 类名称:
    # 类的属性
    xxx = xxx
    
    # 类的行为
    def 方法名(self, 形参1, ......, 形参N):
        方法体
    
# 创建类对象的语法
对象 = 类名称()

可以看到,在方法定义的参数列表中,有一个:self 关键字,self 关键字是成员方法定义的时候,必须填写的

  • 它用来表示类对象自身的意思

  • 当我们使用类对象调用方法的是,self 会自动被 python 传入

  • 在方法内部,想要访问类的成员变量,必须使用 self,如 self.name

注意:self 关键字,尽管在参数列表中,但是传参的时候可以忽略它

2. 构造方法

__init__方法,称之为构造方法,该方法可以实现:

  • 在创建类对象(构造类)的时候,会自动执行

  • 在创建类对象(构造类)的时候,将传入参数自动传递给__init__方法使用

class student:
    name = None
    age = None
    tel = None
    
    # 定义该方法后,以上定义类属性的语句都可以省略
    def __init__(self, name, age, tel):
        self.name = name
        self.age = age
        self.tel = tel
​
stu = student("周杰轮", 31, "18500006666")

___str__字符串方法

class student:
    def __init__(self, name, age):
        self.name = name
        self.age = age
​
student = student("周杰轮", 11)
print(student)      # 结果: <__main__.student object at ox000002200CFD7040>
print(str(student)) # 结果: <__main__.student object at 0x000002200CFD7040>

如上代码所示,当类对象需要被转换为字符串之时,会输出内存地址,内存地址没有多大作用,我们可以通过__str__()方法,控制类转换为字符串的行为。

class student:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __str__(self):
        return f"student类对象,name={self.name},age={self.age}"
​
student = student("周杰轮", 11)
print(student)          # 结果: student类对象,name=周杰轮,age=11
print(str(student))     # 结果: student类对象,name=周杰轮,age=11

__lt__小于符号比较方法

class student:
    def __init__(self,name,age):
        self.name = name
        self.age = age
​
stu1 = student("周杰轮", 11)
stu2 = student("林军杰", 13)
print(stu1 < stu2)
​
"""
    结果:
    Traceback (most recent call last):
        File "D:\python-learn\test.py", line 11, in <module>
            print(stu1 < stu2)
    TypeError: '<' not supported between instances of 'Student' and 'Student'
​
"""

直接对 2 个对象进行比较是不可以的,但是在类中实现__lt__方法,即可同时完成:小于符号和大于符号 2 种比较。

class Student:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __lt__(self, other):
        return self.age < other.age
​
stu1 = student("周杰轮", 11)
stu2 = student("林军杰", 13)
print(stu1 < stu2)      # 结果: True
print(stu1 > stu2)      # 结果: False

__le__小于等于比较符号方法

可用于:<=、>= 两种比较运算符上。

class student:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def __le__(self,other):
        return self.age <= other.age
​
stu1 = student("周杰轮",11)
stu2 = student("林军杰",13)
print(stu1 <= stu2)     # 结果: True
print(stu1 >= stu2)     # 结果: False

__eq__比较运算符实现方法

  • 不实现__eq__方法,对象之间可以比较,但是是比较内存地址,也即是:不同对象比较,一定是 False 结果。

  • 实现了__eq__方法,就可以按照自己的想法来决定 2 个对象是否相等了。

class student:
    def __init__(self, name, age):
        self.name = name
        self.age = age
​
    def __eq__(self, other):
        return self.age == other.age
​
stu1 = student("周杰轮", 11)
stu2 = student("林军杰", 11)
print(stu1 == stu2)     # 结果: True

3. 面向对象三大特性

封装、继承、多态

4. 封装

① 将现实世界事物在类中描述为属性和方法,即为封装。

② 私有成员,定义私有成员的方式非常简单,只需要:

  • 私有成员变量:变量名以__开头(2个下划线)

  • 私有成员方法:方法名以__开头(2个下划线)

即可完成私有成员的设置。

class Phone:
    IMEI = None     # 序列号
    producer = None # 厂商
​
    __current_voltage = None    # 当前电压,私有成员变量
​
    def call_by_5g(self):
        print("5g通话已开启")
​
    def __keep_single_core(self):   # 私有成员方法
        print("让CPU以单核模式运行以节省电量")

注意:

  • 类对象无法访问私有成员

  • 类中的其它成员可以访问私有成员

5. 继承一

① 继承将从父类那里继承(复制)成员变量和成员方法到子类(不含私有)

② 单继承

语法:

class 类名(父类名):
    类内容体

③ 多继承

语法:

class 类名(父类1, 父类2, ......, 父类N):
    类内容体

注意:多个父类中,如果有同名的成员,那么默认以继承顺序(从左到右)为优先级。即:先继承的保留,后继承的被覆盖。

③ pass 关键字

pass 是占位语句,用来保证函数(方法)或类定义的完整性,表示无内容,空的意思,可用于构造抽象方法。

class Phone:
    def call_by_5g(self):
        pass

6. 继承二

① 复写

子类继承父类的成员属性和成员方法后,如果对其“不满意”,那么可以进行复写,即在子类中重新定义同名的属性或方法即可。

class Phone:
    IMEI = None     # 序列号
    producer = "Guizi"  # 厂商
​
    def call_by_5g(self):
        print("5g通话已开启")
        
class MyPhone(Phone):
    producer = "SamoPig"    # 复写父类属性
​
    def call_by_5g(self):   # 复写父类方法
        print("子类的 5g 通话")

② 调用父类同名成员

一旦复写父类成员,那么类对象调用成员的时候,就会调用复写后的新成员;如果类定义中需要使用被复写的父类的成员,需要特殊的调用方式:

Ⅰ. 调用父类成员

  • 使用成员变量:父类名.成员变量

  • 使用成员方法:父类名.成员方法(self)

Ⅱ. 使用 super() 调用父类成员

  • 使用成员变量:super().成员变量

  • 使用成员方法:super().成员方法()

class Phone:
    IMEI = None         # 序列号
    producer = "ITCAST" # 厂商
​
    def call_by_5g(self):
        print("父类的5g通话")
​
c1ass MyPhone(Phone):
    producer = "ITHEIMA""
​
    def call_by_5g(self):
        # 方式1调用父类成员
        print(f"父类的品牌是:{Phone.producer}")
        Phone.call_by_5g(self)
​
        # 方式2调用父类成员
        print(f"父类的品牌是:{super().producer}")
        super().call_by_5g()
        print("子类的5g通话")

注意:只可以在子类内部调用父类的同名成员,子类的实体类对象调用默认是调用子类复写的。

7. 多态

① 多态指的是同样的行为(函数),传入不同的对象,得到不同的状态。如,定义函数(方法),通过类型注解声明需要父类对象,实际传入子类对象进行工作,从而获得不同的工作状态。

  • 抽象类:含有抽象方法的类称之为抽象类。

  • 抽象方法:方法体是空实现的(pass)称之为抽象方法。

② 多态中通常父类的方法是空实现,这种设计的含义是

  • 父类用来确定有哪些方法

  • 具体的方法实现,由子类自行决定。

c1ass Animal:
    def speak(self):
        pass
​
class Dog(Animal):
    def speak(self):
        print("汪汪汪")
​
class Cat(Animal):
    def speak(self):
        print("瞄喵喵")
​
def make_noise(animal: Animal):
    animal.speak()
​
dog = Dog()
cat = Cat()
​
make_noise(dog)     # 输出: 汪汪汪
make_noise(cat)     # 输出: 喵喵瞄

③ 作用:

  • 多用于做顶层设计(设计标准),以便子类做具体实现。

  • 也是对子类的一种软性约束,要求子类必须复写(实现)父类的一些方法,并配合多态使用,获得不同的工作状态。

8. 变量类型注解

在代码中涉及数据交互的地方,提供数据类型的注解(显式的说明)。主要功能:

  • 帮助第三方IDE工具(如PyCharm)对代码进行类型推断,协助做代码提示。

  • 帮助开发者自身对变量进行类型注释。

① 语法一:变量名: 类型

Ⅰ. 基础数据类型注解

var_1: int = 10
var_2: float = 3.1415926
var_3: bool = True
var_4: str = "itheima"

Ⅱ. 类对象类型注解

class student:
    pass
stu: student = student()

Ⅲ. 基础容器类型注解

my_list: list = [1,2,3]
my_tuple: tuple = (1,2,3)
my_set: set = {1,2,3}
my_dict: dict = {"itheima": 666}
my_str: str = "itheima"

Ⅳ. 容器类型详细注解

my_list: list[int] =[1, 2, 3]
my_tuple: tuple[str, int, bool] = ("itheima", 66, True)     # 注意
my_set: set[int] = {1, 2, 3}
my_dict: dict[str, int] = {"itheima": 666}                  # 注意

注意:

  • 元组类型设置类型详细注解,需要将每一个元素都标记出来。

  • 字典类型设置类型详细注解,需要 2 个类型,第一个是 key,第二个是 value。

② 语法二:# type: 类型

注意:

  • 设置注解的情况一般是无法直接看出变量类型时,添加变量的类型注解。

  • 类型注解只是提示性的,并非决定性的,即数据类型和注解类型无法对应也不会导致错误.

9. 函数(方法)类型注解

① 形参类型注解:

def 函数方法名(形参名: 类型, 形参名: 类型, ......):
    pass

② 返回值类型注解:

def 函数方法名(形参: 类型, ......, 形参: 类型) -> 返回值类型:
    pass

示例:

def func(x: int, y: int) -> int:
    pass

10. Union 类型

使用 Union 可以定义联合类型注解,可以表示联合类型注解中的任意一个。

# 导包
from typing import Union
​
# Union[类型, ......, 类型]
def func(data: Union[int, str]) -> Union[int, str]:
    pass

二、数据库

1. 安装第三方库

语法:pip install pymysql

2. 执行 SQL 语句

from pymysql import Connection
​
# 一、获取到 MySQL 数据库的链接对象
conn = Connection(
    host='localhost',   # 主机名(或 IP 地址)
    port=3306,          # 端口,默认 3306
    user='root',        # 账户名
    password='123456'   # 密码
)
    
# 二、获取游标对象
cursor = conn.cursor()
conn.select_db("test")  # 选择数据库
​
# 三、使用游标对象,执行sql语句
cursor.execute("SELECT * FROM student")
# 获取查询结果,得到的数据结构为 ((xx, xx, xx), ... , (xx, xx, xx))
results: tuple = cursor.fetchall()
for r in results:
    print(r)
    
# 四、关闭到数据库的链接
conn.close()

3. commit 提交

① pymysql 库在执行对数据库有修改操作的行为时,是需要通过链接对象的 commit 成员方法来进行确认的,只有确认的修改,才能生效中。

from pymysql import Connection
​
conn = Connection(
    host='localhost',   # 主机名(或 IP 地址)
    port=3306,          # 端口,默认 3306
    user='root',        # 账户名
    password='123456'   # 密码
)
    
cursor = conn.cursor()
conn.select_db("test")  # 选择数据库
​
cursor.execute("insert into student values(10001,'周杰轮',31,'男')")
​
# 通过 commit 确认
conn.commit()
​
conn.close()

② 创建数据库连接时,设置自动提交:autocommit=True

conn = Connection(
    host="localhost",
    port=3306,
    user="root",
    password="123456",
    autocommit=True     # 自动提交
)
  • 35
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值