大家好,在之前的文章中,我们学习了类的基础、继承、多继承以及面向对象的高级特性。今天我们将深入三个进阶主题:动态添加类成员、元类(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 面向对象编程中较为进阶的部分,理解它们有助于更好地阅读框架源码和构建健壮的应用。
如果觉得这篇内容对你有帮助,欢迎收藏备用




