欢迎光临
我们一直在努力

Python 动态添加类成员、元类与异常类完全指南

大家好,在之前的文章中,我们学习了类的基础、继承、多继承以及面向对象的高级特性。今天我们将深入三个进阶主题:动态添加类成员、元类(Metaclass) 以及异常类(Exception)。这三个知识点分别对应了 Python 的灵活性、底层机制和错误处理,是构建健壮、可扩展系统的重要基础。


一、动态添加类成员

1.1 什么是动态添加

Python 允许在运行时动态地为类或实例添加属性、方法。这是 Python 动态特性的重要体现。

class Person:
def __init__(self, name: str):
self.name = name

# 创建实例
p = Person("张三")

# 动态添加实例属性
p.age = 25
p.city = "北京"

print(p.name) # 张三
print(p.age) # 25

1.2 使用 setattr() 动态添加

setattr() 支持属性名动态指定:

class Student:
pass

s = Student()

# 动态设置属性(属性名可以是字符串变量)
setattr(s, "name", "李四")
setattr(s, "score", 95)

# 动态获取
print(getattr(s, "name")) # 李四
print(getattr(s, "score")) # 95

# 批量添加
attrs = {"grade": 3, "major": "计算机科学", "gpa": 3.8}
for key, value in attrs.items():
setattr(s, key, value)

print(s.major) # 计算机科学

1.3 动态添加方法

class Calculator:
pass

# 定义外部函数
def add(self, a, b):
return a + b

def multiply(self, a, b):
return a * b

# 动态添加到类
Calculator.add = add
Calculator.multiply = multiply

calc = Calculator()
print(calc.add(3, 5)) # 8
print(calc.multiply(3, 5)) # 15

1.4 为单个实例添加方法

使用 types.MethodType 可以为特定实例添加方法,而不影响其他实例:

import types

class Person:
def __init__(self, name: str):
self.name = name

p1 = Person("张三")
p2 = Person("李四")

# 定义方法
def greet(self):
return f"你好,我是 {self.name}"

# 只给 p1 添加方法
p1.greet = types.MethodType(greet, p1)

print(p1.greet()) # 你好,我是 张三
# print(p2.greet()) # AttributeError

1.5 使用 __slots__ 限制动态添加

class Person:
__slots__ = ["name", "age"] # 只允许这两个属性

def __init__(self, name: str):
self.name = name

p = Person("张三")
p.age = 25 # 可以
# p.city = "北京" # AttributeError

1.6 动态添加类属性与类方法

class Config:
pass

# 动态添加类属性
Config.DEBUG = True
Config.PORT = 8000

# 动态添加类方法
@classmethod
def get_config(cls):
return {k: v for k, v in cls.__dict__.items() if not k.startswith("_")}

Config.get_config = get_config

print(Config.DEBUG) # True
print(Config.get_config()) # {'DEBUG': True, 'PORT': 8000, …}


二、元类(Metaclass)

2.1 什么是元类

在 Python 中,类也是对象。既然类是对象,那么它一定是由某个"类"创建的。这个创建类的类就是元类(Metaclass)。

class Person:
pass

# 查看 Person 的类是什么
print(type(Person)) # <class 'type'>

# type 就是 Python 的默认元类
# 普通对象是类的实例,类是 type 的实例
python

# type 的作用关系
obj = Person() # obj 是 Person 的实例
Person = type(…) # Person 是 type 的实例

# 检查
print(isinstance(obj, Person)) # True

print(isinstance(Person, type)) # True

2.2 type:内置元类

type 有两个用途:

用途说明
type(obj) 查看对象的类型
type(name, bases, dict) 动态创建类

# 用途一:查看类型
print(type(123)) # <class 'int'>
print(type("hello")) # <class 'str'>

# 用途二:动态创建类
# type(类名, 父类元组, 属性字典)
MyClass = type("MyClass", (object,), {
"x": 10,
"hello": lambda self: "Hello"
})

obj = MyClass()
print(obj.x) # 10
print(obj.hello()) # Hello

2.3 使用 type 动态创建类

# 普通定义方式
class Student:
school = "北京大学"

def __init__(self, name):
self.name = name

def info(self):
return f"{self.name},{self.school}"

# 等价于用 type 创建
def __init__(self, name):
self.name = name

def info(self):
return f"{self.name},{self.school}"

Student = type(
"Student",
(object,),
{
"school": "北京大学",
"__init__": __init__,
"info": info
}
)

s = Student("张三")
print(s.info()) # 张三,北京大学

2.4 自定义元类

继承 type 可以创建自定义元类,在类创建时进行拦截和修改。

class UpperAttrMeta(type):
"""自定义元类:将类中的所有属性名转为大写"""

def __new__(cls, name, bases, attrs):
# 处理属性名:转换为大写
uppercase_attrs = {}
for key, value in attrs.items():
if not key.startswith("__"):
uppercase_attrs[key.upper()] = value
else:
uppercase_attrs[key] = value

return super().__new__(cls, name, bases, uppercase_attrs)

# 使用元类
class MyClass(metaclass=UpperAttrMeta):
name = "张三"
age = 25

def greet(self):
return "Hello"

# 属性名被转为大写
print(MyClass.NAME) # 张三
print(MyClass.AGE) # 25
# print(MyClass.name) # AttributeError

2.5 元类的 __new__ 与 __init__

方法触发时机主要用途
__new__ 创建类对象时 修改类属性、添加类成员
__init__ 类对象创建后 初始化类对象

class MyMeta(type):
def __new__(cls, name, bases, attrs):
print(f"__new__: 创建类 {name}")
attrs["created_by"] = "MyMeta"
return super().__new__(cls, name, bases, attrs)

def __init__(cls, name, bases, attrs):
print(f"__init__: 初始化类 {name}")
super().__init__(name, bases, attrs)

class Demo(metaclass=MyMeta):
pass

# __new__: 创建类 Demo
# __init__: 初始化类 Demo
print(Demo.created_by) # MyMeta


三、异常类(Exception)

3.1 什么是异常类

异常类是 Python 中用于错误处理的机制。当程序出现错误时,会抛出一个异常对象,可以使用 try…except 捕获并处理。

3.2 异常类的层次结构

text

BaseException
├── SystemExit
├── KeyboardInterrupt
├── GeneratorExit
└── Exception
├── ValueError
├── TypeError
├── IndexError
├── KeyError
├── FileNotFoundError
├── RuntimeError
└── …

3.3代码演示

while True:
try:
v1 = int(input("输入第一个数字,输入的信息要是数字格式"))
v2 = int(input("输入第二个数字,输入的信息要是数字格式,不能输入0"))
v3 = v1 / v2
print(f"结果为{v3}")
except ValueError as e:
print(f"类型错误,{e}")
except ZeroDivisionError as e:
print(f"除数错误,{e}")
except Exception as e:
print(f"未知错误",e)
else:
print(f"运算正常")
finally:
print(f"本轮运算结束")


四、总结

知识点核心要点
动态添加属性 obj.attr = value 或 setattr(obj, name, value)
动态添加方法 Class.method = func 或 types.MethodType
元类 type type(obj) 查看类型,type(name, bases, dict) 创建类
自定义元类 继承 type,重写 __new__ 或 __init__
元类应用 单例模式、ORM、自动注册、属性改写
异常类 继承 Exception,自定义错误类型
异常处理 try…except…else…finally

动态添加类成员让 Python 更加灵活,元类让我们能够控制类的创建过程,异常类则为程序提供了完善的错误处理机制。这三个知识点共同构成了 Python 面向对象编程中较为进阶的部分,理解它们有助于更好地阅读框架源码和构建健壮的应用。

如果觉得这篇内容对你有帮助,欢迎收藏备用

赞(0)
未经允许不得转载:171主机测评 » Python 动态添加类成员、元类与异常类完全指南
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址