当前位置:首页>python>Python 核心特性进阶

Python 核心特性进阶

  • 2026-10-21 13:27:08
Python 核心特性进阶

点击上方 蓝字 关注mini猴👆 

免费获取最新最全的100+AI知识库  一起学 AI 大模型

一、面向对象核心特性(封装、继承、多态)

1.1 封装、继承、多态概述

好处:提高代码复用,支持多态 弊端:耦合性增加了

1.1.1 继承

  • 单继承:一个子类只继承一个父类。
  • 多继承:一个子类同时继承多个父类。从左往右,就近原则
  • 多层继承:C继承了B,B继承了A这样结构的多层继承关系

mro机制:

print(Prentice.mro())# Prentice ——》School ——》Master ——》object

子类访问父类成员方法:

  1. 父类名.父类函数名(self) --> 精准访问,想找哪个父类,就调用哪个父类
  2. super().父类函数名() --> 只能访问最近的哪个父类,有就用,没有就往后继续查找后一个继承的类有没有,找不到就报错

self:本类的引用 super:父类的引用

# 师傅类
classMaster:
# 1.1 属性
def__init__(self):
        self.kongfu = '[古法煎饼果子配方]'

# 1.2 行为
defmake_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')  # 打印:运用[古法煎饼果子配方]制作煎饼果子


# 学校类
classSchool:
# 2.1 属性
def__init__(self):
        self.kongfu = '[黑马AI煎饼果子配方]'

# 2.2 行为
defmake_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')  # 打印:运用[黑马AI煎饼果子配方]制作煎饼果子


# 徒弟类(继承自 School 和 Master)
classPrentice(School, Master):
# 3.1 属性
def__init__(self):
        self.kongfu = '[独创煎饼果子配方]'

# 3.2 行为
defmake_cake(self):
        print(f'运用{self.kongfu}制作煎饼果子')  # 打印:运用[独创煎饼果子配方]制作煎饼果子

# 3.3 调用父类的功能
defmake_master_cake(self):
        Master.__init__(self)
        Master.make_cake(self)  # 调用 Master 类的 make_cake 方法


# 4. 测试
if __name__ == '__main__':
# 4.1 创建徒弟类对象
    p = Prentice()

# 4.2 访问属性
    print(p.kongfu)  # 打印:[独创煎饼果子配方]

# 4.3 调用函数
    p.make_cake()  # 打印:运用[独创煎饼果子配方]制作煎饼果子
    p.make_master_cake()  # 打印:运用[古法煎饼果子配方]制作煎饼果子
    print('-' * 34)  # 打印:----------------------------------
    p.make_cake()  # 打印:运用[古法煎饼果子配方]制作煎饼果子

1.1.2 封装

私有属性和私有方法 好处:提高代码的复用性和安全性  弊端:代码量增加了 

1.1.3 多态

多态指的是多种状态,意思是同一个事物在不同场景下表现的不同形态和状态 前提条件:

  1. 要有继承.
  2. 要有方法重写,不然多态无意义.
  3. 要有父引用指向子类对象.

但是python是弱类型语言,没有这些前提条件也能运行

多态的好处:在不改变框架代码的情况下,通过多态语法轻松的实现模块和模块之间的解耦合;实现了软件系统的可拓展。

1.1.4 总结

1.1.5 抽象类

抽象类在python中一般充当父类,用于表示行业的标准、准则。 

1.2 类方法和静态方法

1.2.1 类方法

这里的cls不是关键字,可以随便换变量名 

1.2.2 静态方法

1.2.3 区别

二者除了第一个参数,类方法表示类对象以外,以及装饰器不一样,其他没有任何区别

二、闭包和装饰器

闭包可以保存函数内的变量,而不会随着调用完函数而销毁

2.1 闭包

闭包的构成条件:

  • 有嵌套:在函数嵌套(函数里面再定义函数)的前提下;外部函数嵌套内部函数。
  • 有引用:内部函数使用了外部函数的变量(还包括外部函数的参数)。
  • 有返回:外部函数返回了内部函数名。
deffn_outer(num1):
# 2. 定义内部函数
deffn_inner(num2):
# 有嵌套
# 3. 求和
        sum = num1 + num2  # 有引用
        print(f'求和结果:{sum}')
return fn_inner  # 有返回

# 4.调用上述的函数
fn_inner = fn_outer(10)
fn_inner(20) 
#求和结果:30
print('-' * 23)

fn_outer(100)(200) #求和结果:300

2.2 nonlocal 关键字

它是python内置的关键字,可以实现在内部函数中修改外部函数的变量值

deffn_outer():
# 2. 定义外部函数的(局部)变量
    a = 100

# 3. 定义内部函数,访问外部函数的变量
deffn_inner():
# 4. 在内部函数中修改外部函数的变量
nonlocal a  # nonlocal:可以实现在内部函数中修改外部函数的变量
        a = a + 1
# 5. 打印外部函数的变量
        print(f'a: {a}')

# 6. 返回 内部函数名(对象)
return fn_inner

# 7. 测试
if __name__ == '__main__':
    fn_inner = fn_outer()
    fn_inner()  # 101
    fn_inner()  # 102
    fn_inner()  # 103

2.3 装饰器

装饰器的用法:

  1. 格式1:传统写法: 装饰后的函数名 = 装饰器名(被装饰的原函数名) 装饰后的函数名()
  2. 格式2:语法糖: 在要被装饰的原函数上,直接写 @装饰器名,之后直接调用原函数即可.
"""
案例:装饰器入门.

装饰器介绍:
概述/作用:
它的本质是一个闭包函数,目的是 在不改变原有函数的基础上,对其功能做增强。
大白话:装修队 在不改变房屋结构的情况下,对房屋做装饰(功能增强)

前提条件:
1. 有嵌套.
2. 有引用.
3. 有返回.
4. 有额外功能.

装饰器的用法:
格式1:传统写法.
    装饰后的函数名 = 装饰器名(被装饰的原函数名)
    装饰后的函数名()

格式2:语法糖.
    在要被装饰的原函数上,直接写 @装饰器名,之后直接调用原函数即可.

"""


# 需求:在发表评论前,都需要先登录的.
defcheck_login(fn_name):# fn_name: 被装饰的函数名(对象)  check_login是个装饰器
# 1.1 定义内部函数
deffn_inner():# 有嵌套
# 1.2 额外功能
        print('校验登陆...登陆成功!')
# 1.3 访问原函数,即:外部函数的引用
        fn_name()  # 有引用
# 1.4 返回内部函数对象
return fn_inner  # 有返回

# 2. 定义函数,表示发表评论
defcomment():
    print("发表评论")

# 3.2 语法糖
@check_login # 底层其实是:payment=check_login(payment)
defpayment():
    print('充值中...')

# 3. 测试
# 3.1 传统方式
fn_inner = check_login(comment)
fn_inner()

# 3.2 语法糖
payment()

装饰器的 内部函数 格式要和 被装饰的原函数 保持一致。 即:原函数是无参无返回的,则 装饰器的内部函数也必须是 无参无返回的;原函数有参有返回的,则 装饰器的内部函数也必须是 有参有返回的.

在函数定义里要用 *args;在函数体里用 args(不带 *)

  • 是 Python 的可变参数运算符,它的作用方向由「场景」决定:
  • ✅ 函数定义时:def func(*args): → * 是「打包符」,把多个零散的位置参数打包成一个元组(tuple),赋值给 args;
  • ✅ 函数调用时:func(*args) → * 是「解包符」,把一个元组 / 列表拆成多个零散的位置参数,传给函数。

**kwargs 同理:定义时打包关键字参数为字典,调用时解包字典为关键字参数。

defget_sum(*args):
    print(args)   # args 是一个元组

defget_sum(*args):
    total = sum(args)   # 直接用 args
return total
# 什么时候在函数体里也会写*?
deff(*args):
    g(*args)   # 这里的 *args 是“解包”,不是“打包”


# 1. 定义装饰器
defprint_info(func):
definner(*args, **kwargs):# 有嵌套
        print("【友好提示】正在努力计算中...")
return func(*args, **kwargs)  # 有引用 这里其实是解包操作 *args 把元组 (1,3,4,5) 拆成 1,3,4,5 四个位置参数; **kwargs 把字典 {'a':10,...} 拆成 a=10, b=20, c=30 三个关键字参数;
return inner  # 有返回

# 2. 定义函数,并添加语法糖
@print_info  # args元组,kwargs字典
defget_sum(*args, **kwargs):
    result = 0
for value in args:
        result += value
for value in kwargs.values():
        result += value
return result

# 3. 调用
result = get_sum(1, 3, 4, 5, a=10, b=20, c=30)
print("计算结果:", result)

2.4 多个装饰器装饰一个函数

"""
案例:演示多个装饰器装饰1个函数.

记忆:
    多个装饰器装饰1个原函数,是按照 由内向外的顺序来装饰的,
    但如果你要是用 装饰器的写法来做,看到的效果是:从上往下执行的.

"""


# 需求:发表评论前,需要先登录,在验证验证码,请用所学,模拟该功能.
# 1. 定义装饰器,表示:登录

# 1. 定义装饰器,表示:校验登陆
defcheck_login(fn_name):
deffn_inner():
# 1.2 额外功能
        print('校验登陆!')
# 1.3 有引用
        fn_name()
# 1.4 返回内部函数
return fn_inner

# 2. 定义装饰器,表示:验证验证码
defcheck_code(fn_name):
# 2.1 定义内部函数
deffn_inner():
# 2.2 额外功能
        print('校验验证码!')
# 2.3 有引用
        fn_name()
# 2.4 有返回
return fn_inner

# 3. 定义原函数,表示:发表评论
@check_login
@check_code
defcomment():
    print('发表评论')

# 4.测试
# 4.1 传统写法
comment = check_code(comment)
comment = check_login(comment)
comment()

# 4.2 语法糖
# comment()

2.5 带有参数的装饰器

优化版:

defmy_decorator(fn_name):# fn_name: 要被装饰的函数名(对象)
# 1.1 定义内部函数,格式要和原函数保持一致
deffn_inner(a, b):
# 1.2 增加额外功能
if fn_name.__name__ == 'get_sum':
            print('正在努力计算 [加法] 中...')
elif fn_name.__name__ == 'get_sub':
            print('正在努力计算 [减法] 中...')

# 1.3 有引用
return fn_name(a, b)

# 1.4 有返回
return fn_inner

# 2. 定义原函数,表示:加法运算
@my_decorator
defget_sum(a, b):
return a + b

# 3. 定义原函数,表示:减法运算
@my_decorator
defget_sub(a, b):
return a - b

2.6 浅拷贝和深拷贝

所谓的深浅拷贝分别指的是:

  • 浅拷贝:copy 模块的 copy() 函数
  • 深拷贝:copy 模块的 deepcopy() 函数

大白话解释深浅拷贝:

  • 深拷贝拷贝的多,浅拷贝拷贝的少。

深浅拷贝主要是针对可变类型来讲的:

  • 深拷贝拷贝所有层(可变),浅拷贝只拷贝第 1 层(可变)
  • 如果是针对不可变类型,则用法和普通赋值一样,并无区别。
  1. 普通赋值 
  2. 浅拷贝拷贝可变类型
  3. 浅拷贝拷贝不可变类型 不可变类型和普通赋值一样,不可变类型没法开辟新的空间 
  4. 深拷贝拷贝可变类型 拷贝所有的(可变的)层
  5. 深拷贝拷贝不可变类型

欢迎扫描下方二维码 🔗 领取AI大模型资料

如果觉得本文有用的话,感谢点赞、在看➕关注👆,我是mini猴,咱们下次再见❗️

#AI #大模型

最新文章

随机文章