目录
- 专栏列表
- 前言
- 变量命名规则说明:
- 一、类的内部变量和特殊方法
- 1.1 内部变量
- 示例
- 测试结果:
 
- 1.2 `__slots__`
- 未使用`__slots__`
- 使用`__slots__`
 
 
- 二、装饰器
- 2.1 函数装饰器
- 示例
 
- 2.2 @property
- 示例
 
 
- 三、枚举类
- 3.1 枚举类概述
- 3.2 枚举类定义
- 示例
 
 
- 四、元类
- 4.1 什么是元类
- 4.2 自定义元类
- 示例
 
 
- 结语
 
专栏列表
- Python教程(一):环境搭建及PyCharm安装
- Python 教程(二):语法与数据结构
- Python 教程(三):字符串特性大全
- Python 教程(四):Python运算符合集
- Python 教程(五):理解条件语句和循环结构
- Python 教程(六):函数式编程
- Python 教程(七):match…case 模式匹配
- Python 教程(八):高级特性【高逼格代码】
- Python 教程(九):内置模块与第三方模块
- Python教程(十):面向对象编程(OOP)
- Python教程(十一):单元测试与异常捕获

正文开始,如果觉得文章对您有帮助,请帮我三连+订阅,谢谢💖💖💖
前言
在学习了Python的基本面向对象编程(OOP)概念之后,本篇文章将深入探讨Python中的高级OOP特性。这些特性包括类的内部变量、特殊方法(Magic Methods)、装饰器、枚举类以及元类。通过对这些高级特性的介绍和实例演示,帮助你更好地掌握Python的面向对象编程。
变量命名规则说明:
单下划线、双下划线、头尾双下划线
-  _foo: 以单下划线开头的表示的是protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于from module import *
-  __foo__: 定义的是特殊方法,一般是系统定义名字 ,类似__init__()之类的。
-  __foo: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了。
一、类的内部变量和特殊方法
1.1 内部变量
内部变量(Internal Variables)是指以双下划线开头(__)的变量,它们主要用于防止变量在子类中被意外覆盖。这种命名方式会触发Python的名称改写机制(Name Mangling),使变量名变得难以在类外部访问。
- __init__的特殊方法(构造方法),在生成对象时调用,这个我们已经在前文介绍过了
- __del__: 析构函数,释放对象时使用
- __repr__: 打印,转换
- __setitem__: 按照索引赋值
- __getitem__: 按照索引获取值
- __len__: 获得长度
- __cmp__: 比较运算
- __call__: 函数调用
- __add__: 加运算
- __sub__: 减运算
- __mul__: 乘运算
- __truediv__: 除运算
- __mod__: 求余运算
- __pow__: 乘方
- __str__:定义对象的字符串表示,- print函数调用时使用。
示例
class Container:
    def __init__(self, *args):
        self.container = list(args)  # 初始化容器,接受可变数量的参数
    def __del__(self):
        print(f"对象 {id(self)} 正在被销毁。")
    def __repr__(self):
        return f"Container({self.container})"
    def __setitem__(self, key, value):
        self.container[key] = value  # 索引赋值
    def __getitem__(self, key):
        return self.container[key]  # 索引获取
    def __len__(self):
        return len(self.container)  # 获取容器长度
    def __cmp__(self, other):
        if not isinstance(other, Container):
            return NotImplemented
        return (self.container > other.container) - (self.container < other.container)
    def __call__(self, *args):
        print(f"Container 对象被调用,参数为:{args}")
    def __add__(self, other):
        if isinstance(other, Container):
            return Container(*(self.container + other.container)) # * 是用作解包操作,将list中的参数一个一个的传递,而不是传递一个list
        return NotImplemented
    def __sub__(self, other):
        if isinstance(other, Container):
            return Container(*(self.container[:-1] if len(self.container) >= len(other.container) else self.container))
        return NotImplemented
    def __mul__(self, other):
        if isinstance(other, int):
            return Container(*(self.container * other))
        return NotImplemented
    def __truediv__(self, other):
        if isinstance(other, int) and other != 0:
            return Container(*(x / other for x in self.container))
        return NotImplemented
    def __mod__(self, other):
        if isinstance(other, int):
            return Container(*(x % other for x in self.container))
        return NotImplemented
    def __pow__(self, power):
        return Container(*(x ** power for x in self.container))
    def __str__(self):
        return f"Container 对象: {self.container}"
# 测试代码
if __name__ == "__main__":
    c1 = Container(1, 2, 3)
    c2 = Container(4, 5)
    print(f"c1: {c1}")  # 使用 __str__
    print(f"c2: {c2}")
    c1[1] = 20  # 使用 __setitem__
    print(f"c1 修改后: {c1}")
    print(c1[1])  # 使用 __getitem__
    print(len(c1))  # 使用 __len__
    c3 = c1 + c2  # 使用 __add__
    print(f"c1 + c2: {c3}")
    c4 = c1 - c2  # 使用 __sub__
    print(f"c1 - c2: {c4}")
    c5 = c1 * 2  # 使用 __mul__
    print(f"c1 * 2: {c5}")
    c6 = c1 / 2  # 使用 __truediv__
    print(f"c1 / 2: {c6}")
    c7 = c1 % 3  # 使用 __mod__
    print(f"c1 % 3: {c7}")
    c8 = c1 ** 2  # 使用 __pow__
    print(f"c1 ** 2: {c8}")
    c1(123)  # 使用 __call__
测试结果:

1.2 __slots__
 
__slots__是一个特殊的类属性,用于控制类实例的动态属性的添加。默认情况下,Python的类是基于字典的,这意味着每个实例可以动态地添加任意数量的属性。但是,使用__slots__可以限制实例可以拥有的属性,只允许在__slots__中明确定义的属性。
使用__slots__有以下几个主要好处:
- 节省内存:通过限制属性的数量,可以减少内存的使用,因为不需要为每个实例创建一个字典来存储属性。
- 提高性能:访问预定义的属性比动态属性访问更快,因为预定义属性可以直接通过索引访问。
- 避免意外添加属性:使用__slots__可以确保类的实例不会意外地添加未定义的属性。
未使用__slots__
 
class Person:
    __init(self,*args)__:
      pass
# 创建 Student 类的实例
p = Person()
p.name = '子羽'  
print(p.name)
使用__slots__
 
在定义类时,你可以在类定义的顶部添加一个特殊的__slots__属性,其值为一个包含允许属性名的元组或列表。
class Student:
    __slots__ = ('name', 'age', 'grade')  # 只允许 name, age, grade 三个属性
# 创建 Student 类的实例
s = Student()
s.name = 'Alice'  # 正确,因为 'name' 在 __slots__ 中
s.age = 20        # 正确,因为 'age' 在 __slots__ 中
s.grade = 'A'    # 正确,因为 'grade' 在 __slots__ 中
# 尝试添加未在 __slots__ 中定义的属性
s.address = '123 Main St'  # 抛出 AttributeError
在上面的例子中,尝试给s添加一个不在__slots__列表中的属性address将会抛出AttributeError。
二、装饰器
2.1 函数装饰器
装饰器是一个高阶函数,用于在不改变原函数代码的情况下,动态地增加功能。装饰器通常用于日志记录、性能测试、事务处理等。
示例
def my_decorator(func):
    def wrapper(world):
        print("日志记录开始.")
        func(world)
        print("日志记录结束")
    return wrapper
@my_decorator
def say_hello(world):
    print(f"Hello {world}!")
say_hello('子羽')

2.2 @property
@property 是 Python 中的一个装饰器,用于将一个方法转变为属性访问的形式。这使得你可以使用点符号(.)来访问一个方法,就像访问一个普通的属性一样。
 @property 通常用于当你想要属性值的获取有特定的逻辑处理时,例如,当你需要在获取属性值之前进行验证或计算。
示例
使用 @property 非常简单,你只需要在方法前加上 @property 装饰器,然后在该方法内部定义获取属性值的逻辑。下面是一个简单的例子:
class Circle:
    def __init__(self, radius):
        self._radius = radius  # 私有属性,用来存储圆的半径
    @property
    def radius(self):
        """获取圆的半径"""
        return self._radius
    @radius.setter
    def radius(self, value):
        """设置圆的半径,可以包含验证逻辑"""
        if value < 0:
            raise ValueError("半径不能为负数")
        self._radius = value
# 创建 Circle 类的实例
circle = Circle(5)
# 使用 @property 获取属性
print(circle.radius)  # 输出: 5
# 使用 @setter 设置属性
circle.radius = 10
print(circle.radius)  # 输出: 10
# 尝试设置非法的半径值
circle.radius = -1  # 抛出 ValueError
三、枚举类
3.1 枚举类概述
枚举(Enum)是一种特殊的类,用于表示一组相关的常量值。枚举类中的每个成员都是唯一的,可以使用名称或值进行访问。
3.2 枚举类定义
可以使用Python的 enum 模块定义枚举类。
示例
from enum import Enum, auto
class Color(Enum):
    RED = auto() # 默认从 1 开始
    GREEN = auto()
    BLUE = auto()
    YELLOW = 5
    purple = 6
print(Color.RED)  # 输出: Color.RED
print(Color.GREEN.name)  # 输出: GREEN
print(Color.GREEN.value)  # 输出: 2
print(Color.YELLOW.name)  # 输出: YELLOW
print(Color.YELLOW.value)  # 输出: 5

四、元类
4.1 什么是元类
元类(Metaclass)是用于创建类的类。默认情况下,Python中的所有类都是由 type 元类创建的。通过自定义元类,可以改变类的创建行为。
4.2 自定义元类
自定义元类需要继承自 type,并重写其方法,如 __new__ 和 __init__。
示例
class MyMeta(type):
    def __new__(cls, name, bases, dct):
        print(f"创建新类 :{name}")
        return super().__new__(cls, name, bases, dct)
    def __init__(cls, name, bases, dct):
        print(f"初始化类: {name}")
        super().__init__(name, bases, dct)
class MyClass(metaclass=MyMeta):
    def __init__(self):
        print("创建 Myclass 类的示例")
obj = MyClass()

结语
通过本篇文章,我们深入探讨了Python面向对象编程中的一些高级特性,包括类的内部变量、特殊方法、装饰器、枚举类和元类。这些高级特性能够帮助你编写更加灵活和强大的代码。如果你有任何疑问或想法,欢迎在评论区留言讨论。









![[NPUCTF2020]ReadlezPHP1](https://i-blog.csdnimg.cn/direct/d26eb831cded469e9e61167829c2e617.png)








![[qt] 多线程应用02](https://i-blog.csdnimg.cn/direct/f2fa13b15822489cb37d9a05b7f8fe6c.png)
