当前位置:首页>python>告别if-else!10个高级Python装饰器,让你的代码更干净

告别if-else!10个高级Python装饰器,让你的代码更干净

  • 2026-01-29 22:06:52
告别if-else!10个高级Python装饰器,让你的代码更干净

别再在每个函数里重复写日志、缓存和重试逻辑了

不知道你有没有过这样的经历:看着自己写的代码,同样的日志逻辑出现在十几个函数里,相同的缓存逻辑复制粘贴了七八次,每次添加新功能都要小心翼翼地插入相同的权限检查……

如果你也为此烦恼,那么今天这篇文章就是为你准备的。

我要告诉你一个秘密:Python装饰器,这个看似简单的语法糖,实际上是一把改变你编码方式的"瑞士军刀"。它能让你的代码从"意大利面条"变成整齐的"乐高积木"。

今天,云朵君将为你详细解读10个高级Python装饰器模式,每一个都能解决你实际开发中的痛点。读完这篇文章,你会发现自己不再需要到处复制粘贴相同的代码逻辑了。

为什么装饰器如此强大?

在深入代码之前,我们先花一分钟理解装饰器的本质。

想象一下,你要给一栋房子的每个房间都装上同样的智能照明系统。有两种方法:

  1. 笨方法:在每个房间手动安装相同的电路、传感器和控制器
  2. 聪明方法:在房屋建造时,就把智能照明系统作为标准配置集成进去

装饰器就是那个"聪明方法"。

装饰器的核心价值分离关注点。业务逻辑是业务逻辑,横切关注点(如日志、缓存、权限)是横切关注点。装饰器让它们各司其职,互不干扰。

明白了这个核心理念,云朵君和大家一起开启今天的装饰器之旅吧~

第一部分:性能优化类装饰器

1. TTL缓存装饰器:让缓存自动过期

应用场景:你用了functools.lru_cache,但发现某些数据会随时间变化,需要定期刷新。

痛点:标准LRU缓存不会过期,可能返回陈旧数据。

解决方案:TTL(Time-To-Live)缓存装饰器。

import functoolsimport timedefttl_cache(ttl_seconds):"""缓存装饰器,支持自动过期"""    cache = {}defdecorator(func):        @functools.wraps(func)defwrapper(*args):            now = time.time()# 检查缓存是否存在且未过期if args in cache:                value, timestamp = cache[args]if now - timestamp < ttl_seconds:return value# 缓存未命中或已过期,重新计算            result = func(*args)            cache[args] = (result, now)return resultreturn wrapperreturn decorator# 使用示例@ttl_cache(ttl_seconds=3)defget_weather(city):"""模拟获取天气数据的昂贵操作"""    print(f"Fetching weather for {city}...")    time.sleep(0.5)  # 模拟网络延迟returnf"Weather in {city}: Sunny, 25°C"# 测试print("第一次调用(计算并缓存):")print(get_weather("Beijing"))print("\n第二次调用(1秒后,从缓存读取):")time.sleep(1)print(get_weather("Beijing"))print("\n第三次调用(4秒后,缓存过期,重新计算):")time.sleep(4)print(get_weather("Beijing"))

输出效果

第一次调用(计算并缓存):Fetching weather for Beijing...Weather in Beijing: Sunny, 25°C第二次调用(1秒后,从缓存读取):Weather in Beijing: Sunny, 25°C第三次调用(4秒后,缓存过期,重新计算):Fetching weather for Beijing...Weather in Beijing: Sunny, 25°C

关键点

  • functools.wraps确保装饰后的函数保留原始函数的元数据
  • 使用字典存储(结果, 时间戳)
  • 参数args作为缓存键(对于带有关键字参数的函数需要更复杂的处理)

2. 执行时间跟踪器:快速定位性能瓶颈

应用场景:你的应用变慢了,但不知道是哪个函数拖了后腿。

痛点:手动添加时间测量代码既繁琐又容易遗漏。

解决方案:通用执行时间跟踪装饰器。

import timeimport functoolsdeftimeit(func):"""测量函数执行时间的装饰器"""    @functools.wraps(func)defwrapper(*args, **kwargs):        start = time.perf_counter()  # 使用高精度计时器        result = func(*args, **kwargs)        elapsed = (time.perf_counter() - start) * 1000# 转换为毫秒# 在实际项目中,这里应该使用日志系统而非print        print(f"[PERF] {func.__name__} executed in {elapsed:.2f} ms")return resultreturn wrapper@timeitdefprocess_large_data(n):"""处理大量数据的模拟函数"""return sum(i * i for i in range(n))@timeit  deffetch_from_database(query):"""模拟数据库查询"""    time.sleep(0.1)returnf"Results for {query}"# 测试性能process_large_data(1_000_000)fetch_from_database("SELECT * FROM users")

输出

[PERF] process_large_data executed in 46.32 ms[PERF] fetch_from_database executed in 100.15 ms

进阶技巧:在实际项目中,你可以将这个装饰器与日志级别结合,只在需要性能分析时启用它。

第二部分:系统健壮性类装饰器

3. 失败重试装饰器:应对不稳定操作

应用场景:网络请求、文件I/O、第三方API调用等可能偶尔失败的操作。

痛点:到处写重试逻辑使代码变得臃肿。

解决方案:可配置的重试装饰器。

import functoolsimport timeimport randomdefretry(retries=3, delay=1.0, backoff=2.0, exceptions=(Exception,)):"""    重试装饰器    参数:    retries: 最大重试次数    delay: 首次重试延迟(秒)    backoff: 延迟倍数(用于指数退避)    exceptions: 触发重试的异常类型    """defdecorator(func):        @functools.wraps(func)defwrapper(*args, **kwargs):            current_delay = delayfor attempt in range(1, retries + 1):try:return func(*args, **kwargs)except exceptions as e:if attempt == retries:                        print(f"All {retries} attempts failed. Last error: {e}")raise                    print(f"Attempt {attempt} failed: {e}. Retrying in {current_delay:.1f}s...")                    time.sleep(current_delay)                    current_delay *= backoff  # 指数退避# 理论上不会执行到这里returnNonereturn wrapperreturn decorator# 模拟一个不稳定的API调用@retry(retries=4, delay=0.5, backoff=1.5, exceptions=(ConnectionError, TimeoutError))defcall_unstable_api(endpoint):"""模拟不稳定的API调用"""if random.random() < 0.7:  # 70%概率失败raise ConnectionError(f"Failed to connect to {endpoint}")returnf"Success from {endpoint}"# 测试result = call_unstable_api("/api/data")print(f"最终结果: {result}")

输出示例

Attempt 1 failed: Failed to connect to /api/data. Retrying in 0.5s...Attempt 2 failed: Failed to connect to /api/data. Retrying in 0.8s...Attempt 3 failed: Failed to connect to /api/data. Retrying in 1.2s...最终结果: Success from /api/data

指数退避策略:这是处理网络问题的黄金标准。每次失败后等待时间增加,避免给已经过载的服务增加压力。

4. 限流装饰器:防止API滥用

应用场景:公开API、用户操作限制、防止爬虫等。

痛点:在业务逻辑中嵌入限流检查。

解决方案:基于时间的限流装饰器。

import timeimport functoolsdefrate_limit(calls_per_minute):"""限制每分钟调用次数的装饰器"""    interval = 60.0 / calls_per_minutedefdecorator(func):        last_called = [0.0]  # 使用列表实现闭包内的可变状态        @functools.wraps(func)defwrapper(*args, **kwargs):            elapsed = time.time() - last_called[0]if elapsed < interval:# 调用太频繁                wait_time = interval - elapsed                print(f"Rate limit exceeded. Please wait {wait_time:.1f} seconds.")returnNone            last_called[0] = time.time()return func(*args, **kwargs)return wrapperreturn decorator# 限制为每分钟最多10次调用@rate_limit(calls_per_minute=10)defsend_notification(user_id, message):"""发送通知(模拟)"""    print(f"Notification sent to user {user_id}{message}")returnTrue# 测试快速连续调用for i in range(15):    result = send_notification(123f"Message {i}")if result isNone:        time.sleep(0.1)  # 稍微等待后继续测试

线程安全版:对于多线程环境,你需要使用线程锁:

import threadingdefrate_limit_threadsafe(calls_per_minute):    interval = 60.0 / calls_per_minute    lock = threading.Lock()    last_called = 0.0defdecorator(func):        @functools.wraps(func)defwrapper(*args, **kwargs):nonlocal last_calledwith lock:                now = time.time()                elapsed = now - last_calledif elapsed < interval:returnNone                last_called = nowreturn func(*args, **kwargs)return wrapperreturn decorator

第三部分:代码可维护性类装饰器

5. 简易日志装饰器:告别调试print语句

应用场景:调试时临时添加的print语句经常忘记删除,导致生产环境日志混乱。

痛点:日志逻辑与业务逻辑混杂。

解决方案:非侵入式日志装饰器。

import functoolsimport datetimedeflog_call(level="INFO"):"""记录函数调用的装饰器"""defdecorator(func):        @functools.wraps(func)defwrapper(*args, **kwargs):# 记录调用信息            timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")            arg_str = ", ".join([repr(arg) for arg in args])            kwarg_str = ", ".join([f"{k}={repr(v)}"for k, v in kwargs.items()])            all_args = ", ".join(filter(None, [arg_str, kwarg_str]))            print(f"[{timestamp}] [{level}] Calling {func.__name__}({all_args})")# 执行函数            result = func(*args, **kwargs)# 记录返回结果            print(f"[{timestamp}] [{level}{func.__name__} returned {repr(result)}")return resultreturn wrapperreturn decorator@log_call(level="DEBUG")defcalculate_discount(price, discount_rate=0.1, tax_rate=0.08):"""计算折扣后价格"""    discounted = price * (1 - discount_rate)    final_price = discounted * (1 + tax_rate)return round(final_price, 2)# 测试price = calculate_discount(100, discount_rate=0.2)print(f"最终价格: ${price}")

输出

[2024-01-15 10:30:00] [DEBUG] Calling calculate_discount(100, discount_rate=0.2)[2024-01-15 10:30:00] [DEBUG] calculate_discount returned 86.4最终价格: $86.4

生产环境建议:在实际项目中,应该使用Python的logging模块替代print,并支持日志级别过滤。

6. 依赖注入装饰器:告别全局变量

应用场景:函数需要访问数据库连接、配置、日志器等共享资源。

痛点:使用全局变量或到处传递依赖。

解决方案:依赖注入装饰器。

import functoolsdefinject(**dependencies):"""依赖注入装饰器"""defdecorator(func):        @functools.wraps(func)defwrapper(*args, **kwargs):# 临时将依赖注入到函数的全局命名空间            original_globals = func.__globals__.copy()try:# 添加依赖                func.__globals__.update(dependencies)return func(*args, **kwargs)finally:# 恢复原始全局变量for key in dependencies:                    func.__globals__.pop(key, None)# 对于已存在的键,恢复其原始值for key, value in original_globals.items():if key notin func.__globals__:                        func.__globals__[key] = valuereturn wrapperreturn decorator# 模拟一些依赖项classDatabase:defquery(self, sql):returnf"Result: {sql}"classLogger:definfo(self, msg):        print(f"[INFO] {msg}")# 创建依赖实例db = Database()logger = Logger()# 使用依赖注入@inject(db=db, logger=logger)defprocess_order(order_id):    logger.info(f"Processing order {order_id}")    result = db.query(f"SELECT * FROM orders WHERE id={order_id}")    logger.info(f"Query result: {result}")return result# 测试process_order(12345)

更安全的方法:上面的方法修改了全局命名空间,可能带来副作用。更安全的方法是显式传递依赖:

definject_safe(**dependencies):defdecorator(func):        @functools.wraps(func)defwrapper(*args, **kwargs):# 将依赖作为关键字参数传递return func(*args, **dependencies, **kwargs)return wrapperreturn decorator

7. 类装饰器:一次性装饰所有方法

应用场景:你需要给一个类的所有方法添加相同的行为(如日志、计时、权限检查)。

痛点:给每个方法单独添加装饰器。

解决方案:类级别装饰器。

import typesimport functoolsimport timedeftime_all_methods(cls):"""装饰类中所有方法的装饰器"""# 遍历类的所有属性for attr_name in dir(cls):# 跳过特殊方法和私有方法if attr_name.startswith("_"):continue        attr = getattr(cls, attr_name)# 只装饰可调用方法if callable(attr):# 创建装饰后的方法            @functools.wraps(attr)deftimed_method(self, *args, __original_method=attr, **kwargs):                start = time.perf_counter()                result = __original_method(self, *args, **kwargs)                elapsed = (time.perf_counter() - start) * 1000                print(f"{cls.__name__}.{__original_method.__name__} took {elapsed:.2f} ms")return result# 替换原始方法            setattr(cls, attr_name, timed_method)return cls@time_all_methodsclassDataProcessor:def__init__(self, data):        self.data = datadeffilter_data(self):"""过滤数据"""        time.sleep(0.05)return [x for x in self.data if x % 2 == 0]deftransform_data(self):"""转换数据"""        time.sleep(0.03)return [x * 2for x in self.data]defprocess(self):"""完整处理流程"""        filtered = self.filter_data()        transformed = self.transform_data()return transformed# 测试processor = DataProcessor(list(range(1000)))result = processor.process()print(f"处理结果长度: {len(result)}")

输出

DataProcessor.filter_data took 50.12 msDataProcessor.transform_data took 30.05 msDataProcessor.process took 80.25 ms处理结果长度: 1000

注意事项:这种装饰器会影响类的所有实例。如果你只需要装饰特定方法,建议使用元类或显式装饰。

第四部分:高级架构类装饰器

8. 单例装饰器:确保全局唯一实例

应用场景:配置管理、数据库连接池、缓存管理器等需要全局唯一实例的类。

痛点:手动实现单例模式需要重复代码。

解决方案:通用单例装饰器。

import functoolsdefsingleton(cls):"""单例装饰器"""    instances = {}    @functools.wraps(cls)defwrapper(*args, **kwargs):if cls notin instances:            instances[cls] = cls(*args, **kwargs)return instances[cls]return wrapper@singletonclassAppConfig:def__init__(self):        print("Initializing AppConfig...")        self.settings = {"debug"True,"database_url""postgresql://localhost/mydb","cache_ttl"300        }defget(self, key):return self.settings.get(key)defset(self, key, value):        self.settings[key] = value# 测试单例行为config1 = AppConfig()config2 = AppConfig()print(f"config1 is config2: {config1 is config2}")print(f"config1 ID: {id(config1)}")print(f"config2 ID: {id(config2)}")# 验证配置共享config1.set("debug"False)print(f"config2.get('debug'): {config2.get('debug')}")

输出

Initializing AppConfig...config1 is config2: Trueconfig1 ID: 140000000000000config2 ID: 140000000000000config2.get('debug'): False

线程安全版本:对于多线程环境:

import threadingdefsingleton_threadsafe(cls):    instances = {}    lock = threading.Lock()    @functools.wraps(cls)defwrapper(*args, **kwargs):if cls notin instances:with lock:if cls notin instances:  # 双重检查锁定                    instances[cls] = cls(*args, **kwargs)return instances[cls]return wrapper

9. 基于角色的访问控制装饰器

应用场景:Web应用、API服务、管理后台等需要权限控制的系统。

痛点:在每个需要权限检查的函数中重复验证逻辑。

解决方案:RBAC(基于角色的访问控制)装饰器。

import functoolsdefrequire_role(*allowed_roles):"""基于角色的权限检查装饰器"""defdecorator(func):        @functools.wraps(func)defwrapper(user, *args, **kwargs):            user_role = user.get("role""guest")if user_role notin allowed_roles:raise PermissionError(f"User {user.get('name''Unknown')} with role '{user_role}' "f"is not allowed to perform {func.__name__}. "f"Required roles: {allowed_roles}"                )return func(user, *args, **kwargs)return wrapperreturn decorator# 模拟用户数据admin_user = {"id"1"name""Alice""role""admin"}editor_user = {"id"2"name""Bob""role""editor"}viewer_user = {"id"3"name""Charlie""role""viewer"}classContentManagementSystem:    @require_role("admin", "editor")defcreate_article(self, user, title, content):        print(f"{user['name']} created article: {title}")return {"id"100"title": title, "content": content}    @require_role("admin", "editor", "viewer")defview_article(self, user, article_id):        print(f"{user['name']} viewed article {article_id}")return {"id": article_id, "content""Sample content"}    @require_role("admin")defdelete_article(self, user, article_id):        print(f"{user['name']} deleted article {article_id}")return {"success"True}# 测试cms = ContentManagementSystem()# 正常情况cms.create_article(admin_user, "Python Tips""Some content")cms.view_article(viewer_user, 100)# 权限不足的情况try:    cms.delete_article(editor_user, 100)except PermissionError as e:    print(f"权限错误: {e}")

输出

Alice created article: Python TipsCharlie viewed article 100权限错误: User Bob with role 'editor' is not allowed to perform delete_article. Required roles: ('admin',)

10. 上下文管理装饰器:传递请求级信息

应用场景:微服务、异步任务、Web请求处理等需要传递上下文信息的场景。

痛点:通过函数参数层层传递上下文信息(如请求ID、用户信息)。

解决方案:基于contextvars的上下文管理装饰器。

import functoolsimport contextvarsimport uuid# 创建上下文变量request_id_var = contextvars.ContextVar("request_id", default=None)user_context_var = contextvars.ContextVar("user", default=None)defwith_context(func):"""上下文管理装饰器"""    @functools.wraps(func)defwrapper(*args, **kwargs):# 获取当前上下文        request_id = request_id_var.get()        user = user_context_var.get()# 如果没有请求ID,生成一个if request_id isNone:            request_id = str(uuid.uuid4())[:8]            request_id_var.set(request_id)        print(f"[{request_id}] Starting {func.__name__}")if user:            print(f"[{request_id}] User: {user.get('name''Unknown')}")try:            result = func(*args, **kwargs)            print(f"[{request_id}{func.__name__} completed successfully")return resultexcept Exception as e:            print(f"[{request_id}{func.__name__} failed: {e}")raisereturn wrapperdefset_request_context(request_id=None, user=None):"""设置请求上下文"""if request_id:        request_id_var.set(request_id)if user:        user_context_var.set(user)# 模拟一个Web请求处理流程@with_contextdefauthenticate(token):    print(f"Authenticating token: {token[:10]}...")return {"id"123"name""John Doe""role""user"}@with_contextdefprocess_request(data):    user = user_context_var.get()    print(f"Processing request for user: {user['name']}")return {"status""success""data": data}@with_contextdefhandle_api_request(token, request_data):# 认证    user = authenticate(token)    user_context_var.set(user)# 处理请求    result = process_request(request_data)# 记录日志    request_id = request_id_var.get()    print(f"[{request_id}] API request completed")return result# 测试print("=== 测试1:正常请求 ===")set_request_context(request_id="req_001")response = handle_api_request("secure_token_123", {"action""get_data"})print(f"Response: {response}")print("\n=== 测试2:另一个请求 ===")set_request_context(request_id="req_002", user={"id"456"name""Jane Smith"})response = handle_api_request("secure_token_456", {"action""update_data"})print(f"Response: {response}")

输出

=== 测试1:正常请求 ===[req_001] Starting handle_api_requestAuthenticating token: secure_tok...[req_001] Starting authenticate[req_001] authenticate completed successfully[req_001] Starting process_requestProcessing request for user: John Doe[req_001] process_request completed successfully[req_001] API request completedResponse: {'status''success''data': {'action''get_data'}}=== 测试2:另一个请求 ===[req_002] Starting handle_api_request[req_002] User: Jane SmithAuthenticating token: secure_tok...[req_002] Starting authenticate[req_002] authenticate completed successfully[req_002] Starting process_requestProcessing request for user: John Doe[req_002] process_request completed successfully[req_002] API request completedResponse: {'status''success''data': {'action''update_data'}}

异步支持contextvars是Python 3.7+引入的特性,完美支持异步操作。上下文变量会自动在异步任务间传播,这是传统的线程局部变量(threading.local)无法做到的。

写在最后

今天我们一起探索了10个高级Python装饰器模式,从性能优化到系统架构,每个模式都瞄准了实际开发中的痛点。

装饰器的核心价值可以用一句话概括:让横切关注点与业务逻辑分离。这种分离带来的好处是:

  1. 代码更干净:业务逻辑不再被各种辅助代码污染
  2. 维护更容易:功能修改只需在一个地方进行
  3. 复用性更强:装饰器可以在不同项目、不同函数间共享
  4. 可读性更高:通过装饰器名称就能理解函数的附加行为

最后的小提示:装饰器虽好,但不要过度使用。当一个函数被多层装饰器包裹时,调试会变得困难。建议:

  • 保持装饰器简单透明
  • 使用functools.wraps保留元数据
  • 为复杂装饰器编写单元测试

你在项目中还用过哪些有趣的装饰器模式?或者遇到过什么装饰器的"坑"?欢迎在评论区分享你的经验,让我们共同进步!

🏴‍☠️宝藏级🏴‍☠️ 原创公众号『数据STUDIO』内容超级硬核。公众号以Python为核心语言,垂直于数据科学领域,包括可戳👉PythonMySQL数据分析数据可视化机器学习与数据挖掘爬虫等,从入门到进阶!

长按👇关注- 数据STUDIO -设为星标,干货速递

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-02-08 11:03:48 HTTP/2.0 GET : https://f.mffb.com.cn/a/465384.html
  2. 运行时间 : 0.243690s [ 吞吐率:4.10req/s ] 内存消耗:4,871.34kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=60914a021ff6a29be410f3bcfaef0712
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000867s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001593s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.010262s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.003147s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001280s ]
  6. SELECT * FROM `set` [ RunTime:0.005986s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001435s ]
  8. SELECT * FROM `article` WHERE `id` = 465384 LIMIT 1 [ RunTime:0.019089s ]
  9. UPDATE `article` SET `lasttime` = 1770519828 WHERE `id` = 465384 [ RunTime:0.010310s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.002953s ]
  11. SELECT * FROM `article` WHERE `id` < 465384 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.013866s ]
  12. SELECT * FROM `article` WHERE `id` > 465384 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.004707s ]
  13. SELECT * FROM `article` WHERE `id` < 465384 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.007765s ]
  14. SELECT * FROM `article` WHERE `id` < 465384 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.002347s ]
  15. SELECT * FROM `article` WHERE `id` < 465384 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.004909s ]
0.247424s