type() 函数在 Python 中不仅用于检查对象类型,还可以动态创建类。这是 Python 元编程的重要特性。
一、type() 函数的两种用途
1. 查看对象类型(常用方式)
# 查看内置类型print(type(123)) # <class 'int'>print(type("hello")) # <class 'str'>print(type([1, 2, 3])) # <class 'list'>print(type({"a": 1})) # <class 'dict'># 查看自定义类class MyClass: passobj = MyClass()print(type(obj)) # <class '__main__.MyClass'>print(type(MyClass)) # <class 'type'>
2. 动态创建类(元类编程)
# 动态创建类的语法# type(类名, 父类元组, 属性字典)
二、动态创建类的基本用法
1. 创建最简单的类
# 使用type动态创建类MyClass = type('MyClass', (), {})# 等价于# class MyClass:# pass# 创建实例obj = MyClass()print(obj) # <__main__.MyClass object at 0x...>print(type(obj)) # <class '__main__.MyClass'>print(type(MyClass)) # <class 'type'>
2. 创建带属性和方法的类
# 定义方法def say_hello(self): return f"Hello, I'm {self.name}"def __init__(self, name, age): self.name = name self.age = age# 使用type动态创建类Person = type('Person', (), { '__init__': __init__, 'say_hello': say_hello, 'species': '人类' # 类属性})# 使用动态创建的类person = Person("张三", 25)print(person.name) # 张三print(person.age) # 25print(person.say_hello()) # Hello, I'm 张三print(person.species) # 人类print(Person.species) # 人类# 验证print(type(person)) # <class '__main__.Person'>print(isinstance(person, Person)) # True
三、实际应用场景
1. 动态创建数据库模型
def create_model_class(table_name, fields): """动态创建数据库模型类""" def __init__(self, **kwargs): """动态初始化属性""" for field in fields: setattr(self, field, kwargs.get(field, None)) def to_dict(self): """转换为字典""" return {field: getattr(self, field) for field in fields} def __str__(self): values = ', '.join([f"{field}={getattr(self, field)}" for field in fields]) return f"{table_name}({values})" # 创建类字典 class_dict = { '__init__': __init__, 'to_dict': to_dict, '__str__': __str__, '__table__': table_name, '__fields__': fields, '__module__': __name__ } # 动态创建类 return type(table_name, (), class_dict)# 使用:动态创建User模型User = create_model_class('User', ['id', 'username', 'email', 'age'])# 创建实例user = User(id=1, username="zhangsan", email="zhang@example.com", age=25)print(user) # User(id=1, username=zhangsan, email=zhang@example.com, age=25)print(user.to_dict()) # {'id': 1, 'username': 'zhangsan', 'email': 'zhang@example.com', 'age': 25}print(user.__table__) # Userprint(user.__fields__) # ['id', 'username', 'email', 'age']# 动态创建Product模型Product = create_model_class('Product', ['id', 'name', 'price', 'stock'])product = Product(id=101, name="笔记本电脑", price=5999.00, stock=50)print(product) # Product(id=101, name=笔记本电脑, price=5999.0, stock=50)print(product.to_dict())
2. 动态创建API响应类
def create_response_class(status_code, message_template): """动态创建API响应类""" def __init__(self, data=None, **kwargs): self.status_code = status_code self.message = message_template.format(**kwargs) if kwargs else message_template self.data = data or {} import time self.timestamp = time.time() def to_json(self): """转换为JSON格式""" import json return json.dumps({ 'code': self.status_code, 'message': self.message, 'data': self.data, 'timestamp': self.timestamp }, ensure_ascii=False) def __str__(self): return f"Response(code={self.status_code}, message={self.message})" # 创建类 class_name = f"Response{status_code}" return type(class_name, (), { '__init__': __init__, 'to_json': to_json, '__str__': __str__ })# 动态创建各种响应类SuccessResponse = create_response_class(200, "操作成功")NotFoundResponse = create_response_class(404, "资源不存在: {resource}")ValidationErrorResponse = create_response_class(400, "参数验证失败: {errors}")# 使用success = SuccessResponse(data={"user_id": 123})print(success) # Response(code=200, message=操作成功)print(success.to_json())not_found = NotFoundResponse(resource="用户")print(not_found) # Response(code=404, message=资源不存在: 用户)validation_error = ValidationErrorResponse(errors=["邮箱格式错误", "密码太短"])print(validation_error) # Response(code=400, message=参数验证失败: ['邮箱格式错误', '密码太短'])
3. 工厂模式:动态创建不同类型的处理器
def create_data_handler(data_format): """根据数据格式动态创建处理器类""" if data_format == 'json': def process(self, data): import json return json.loads(data) def output(self, data): import json return json.dumps(data, ensure_ascii=False, indent=2) elif data_format == 'xml': def process(self, data): import xml.etree.ElementTree as ET return ET.fromstring(data) def output(self, data): import xml.etree.ElementTree as ET return ET.tostring(data, encoding='unicode') elif data_format == 'csv': def process(self, data): import csv import io reader = csv.DictReader(io.StringIO(data)) return list(reader) def output(self, data): import csv import io output = io.StringIO() if data: writer = csv.DictWriter(output, fieldnames=data[0].keys()) writer.writeheader() writer.writerows(data) return output.getvalue() else: raise ValueError(f"不支持的数据格式: {data_format}") # 创建处理器类 class_name = f"{data_format.upper()}Handler" return type(class_name, (), { 'format': data_format, 'process': process, 'output': output, '__str__': lambda self: f"{data_format.upper()}处理器" })# 动态创建不同类型的处理器handlers = {}for fmt in ['json', 'xml', 'csv']: handlers[fmt] = create_data_handler(fmt)# 使用json_handler = handlers['json']()xml_handler = handlers['xml']()csv_handler = handlers['csv']()# 测试JSON处理器json_data = '{"name": "张三", "age": 25}'result = json_handler.process(json_data)print(f"JSON解析结果: {result}")print(f"JSON格式化输出: {json_handler.output(result)}")# 测试CSV处理器csv_data = "name,age,city\n张三,25,北京\n李四,30,上海"result = csv_handler.process(csv_data)print(f"\nCSV解析结果: {result}")print(f"CSV格式化输出:\n{csv_handler.output(result)}")
总结
type() 函数动态创建类的核心要点:
| | |
|---|
| type('ClassName', (), {}) | |
| type('ClassName', (), {'method': func}) | |
| type('ClassName', (BaseClass,), {}) | |
| type('ClassName', (), {'__metaclass__': Meta}) | |