云计算百科
云计算领域专业知识百科平台

Python.三.(四)--4.类、对象与魔术方法

三、 函数、类与面向对象编程 (OOP)

  • 标题:

    <ol>
    <li>函数参数与高阶函数</li>
    <li>装饰器与闭包</li>
    <li>面向对象三大特征</li>
    <li>类、对象与魔术方法</li>
    <li>异常处理</li>
    </ol>
    </li>

这8个知识点共同构成"Python对象模型的完整图谱":从对象的创建、行为、自省,到元层的控制,环环相扣

🎨 核心逻辑链:元类造类 → 类造对象 → 魔术方法定义对象行为 → 自省让我们观察这一切 → 方法/变量/控制流是日常使用细节。


一、逐点速览

① 自省(Introspection) 🔍
对象在运行时"自我审视"的能力。通过 type()、dir()、hasattr()、getattr()、inspect 等获取对象的类型、属性、方法。

class A: pass
a = A()
print(dir(a)) # 查看所有属性方法
print(type(a)) # <class '__main__.A'>
getattr(a, 'x', None) # 安全取属性

② 实例方法 / 类方法 / 静态方法 ⚖️

类型装饰器首参能否访问实例能否访问类
实例方法 self
类方法 @classmethod cls
静态方法 @staticmethod

③ @staticmethod / @classmethod 使用注意 ⚠️

  • @classmethod 最常见用途:替代构造器(from_xxx 工厂方法)。
  • @staticmethod 用于逻辑上属于类但不依赖类/实例状态的工具函数;若发现它没用到类信息,其实可以提到模块层。
  • 注意:静态方法无法被子类多态重写改变行为(它不接收 cls)。

④ 类变量 vs 实例变量 📦

  • 类变量:定义在类体、方法外,所有实例共享。
  • 实例变量:在 __init__ 中通过 self.xxx 绑定,各实例独有。

class Dog:
species = "Canis" # 类变量(共享)
def __init__(self, name):
self.name = name # 实例变量(独有)

⚠️ 坑:用可变对象(如 list)作类变量会被所有实例共享,易出 bug。

⑤ __new__ vs __init__ 🏗️

  • __new__:创建并返回实例,是类方法(首参 cls),先调用。控制对象的生成(单例、不可变对象缓存必用)。
  • __init__:初始化已有实例,首参 self,后调用。赋值实例变量。

class Singleton:
_inst = None
def __new__(cls, *a, **kw):
if cls._inst is None:
cls._inst = super().__new__(cls)
return cls._inst

⑥ 魔术方法(Dunder Methods) ✨
以双下划线包裹的方法,由 Python 隐式调用,实现运算符重载、协议(迭代、上下文管理等)。例:__init__、__str__、__len__、__call__、__getitem__、__enter__/__exit__。

class Vector:
def __init__(self, x, y): self.x, self.y = x, y
def __add__(self, o): return Vector(self.x+o.x, self.y+o.y) # 重载 +

⑦ 元类(Metaclass) 🧬
"类的类"。普通类是 type 的实例,type 本身就是默认元类。元类控制类的创建行为,常用于 ORM、框架自动注册、接口校验。

class Meta(type):
def __new__(mcs, name, bases, ns):
ns['created_by'] = 'Meta' # 拦截并修改类定义
return super().__new__(mcs, name, bases, ns)
class Foo(metaclass=Meta): pass
print(Foo.created_by) # Meta

⑧ switch-case 实现 🔀
Python 3.10+ 有官方 match-case;旧写法用字典映射或函数分发(闭包/方法表)。

# 字典分发
def op(x, y, code):
return {'add': lambda: x+y, 'sub': lambda: x-y}.get(code, lambda: None)()
match-case (3.10+)
match code:
case 'add': print(x+y)
case 'sub': print(x-y)


二、它们之间的联系 🔗

这是核心。8个点可归为四个层次,层层递进:

🧬 元层: 元类 metaclass
控制"类"如何被创建

🏗️ 创建层: __new__ 造对象 → __init__ 初始化
类变量/实例变量 在此绑定

✨ 行为层: 魔术方法定义对象行为
@classmethod/@staticmethod 定义方法语义

🔍 使用层: 自省观察一切
switch-case 做运行时分发

1. 元类 → __new__/__init__ → 魔术方法(创建链)
元类的 __new__ 创建"类"这个对象;而当我们实例化时,类的 __new__ 创建实例、__init__ 初始化实例——这俩本身就是魔术方法。所以元类管类的诞生,魔术方法管对象的诞生与行为,是同一条"创建流水线"的不同层级。

2. 类变量/实例变量 ↔ __new__/__init__

  • 类变量在类定义时由元类/type 写入类的命名空间。
  • 实例变量在 __init__ 中通过 self 绑定。
  • 两者区别本质是"存储位置不同":一个在类 __dict__,一个在实例 __dict__——而这点正是自省能验证的。

3. 三种方法 ↔ 魔术方法 ↔ 装饰器
@staticmethod、@classmethod 既是装饰器(呼应你上一题),又改变了方法在类中的语义;它们与实例方法一起构成"方法分发"的基础。而魔术方法(如 __call__)是另一种隐式分发机制。switch-case 的字典分发思想,与方法的分派机制同源——都是"用键查表找到可调用对象"。

4. 自省是观察整个体系的"显微镜" 🔬
自省把上面所有概念串起来验证:

  • type(obj) → 看到类;type(cls) → 看到元类。
  • cls.__dict__ → 看到类变量;obj.__dict__ → 看到实例变量。
  • dir(obj) → 列出所有魔术方法和普通方法。
  • inspect.ismethod → 区分实例/类/静态方法。

📌 一句话串联:元类造类、__new__造对象、__init__填变量、魔术法定行为、三种方法定语义、自省察全局、switch-case做分发——从"如何造"到"如何用"到"如何观察",构成 Python 面向对象的完整闭环。

 

赞(0)
未经允许不得转载:网硕互联帮助中心 » Python.三.(四)--4.类、对象与魔术方法
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!