今天我们将深入三个进阶主题:动态添加类成员、元类(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) # 251.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)) # 151.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()) # attributeerror1.5 使用__slots__限制动态添加
class person:
__slots__ = ["name", "age"] # 只允许这两个属性
def __init__(self, name: str):
self.name = name
p = person("张三")
p.age = 25 # 可以
# p.city = "北京" # attributeerror1.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)) # trueprint(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()) # hello2.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) # attributeerror2.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 面向对象编程中较为进阶的部分,理解它们有助于更好地阅读框架源码和构建健壮的应用。
以上就是python动态添加类成员、元类与异常类的完全指南的详细内容,更多关于python动态添加类成员、元类与异常类的资料请关注代码网其它相关文章!
发表评论