当前位置:首页>python>小白VS大佬:同样功能,Python代码差距就在一个@符号

小白VS大佬:同样功能,Python代码差距就在一个@符号

  • 2026-08-18 23:10:23
小白VS大佬:同样功能,Python代码差距就在一个@符号

阿发聊测试 · 技术进阶系列

小白VS大佬:同样功能,Python代码差距就在一个@符号

从0到1彻底搞懂Python装饰器,面试被问到再也不怕

你好,我是阿发。

上周帮一个粉丝改代码,看到一段让我哭笑不得的实现。他要给5个函数加日志,结果每个函数里面都写了一遍logging代码。整整50行重复代码,就为了打印一句"函数XX开始执行"。我说:"你知道装饰器吗?一个@符号就能搞定。"他一脸茫然:"@不是邮箱符号吗?"说实话,这个场景我见过太多了。很多测试工程师写Python只会堆代码,遇到重复逻辑就复制粘贴,完全不知道装饰器这种优雅的解决方案。今天这篇文章,我用"小白VS大佬"的对比方式,把装饰器从概念到实战讲得明明白白。同样的功能,小白写100行,大佬只需要一个@符号。

SECTION 01

开场:同样的功能,两种写法对比

先来看一个真实场景:你需要给多个函数添加执行时间统计功能。比如有登录、注册、查询用户三个接口测试函数,你想知道每个函数执行了多久。

小白写法:重复代码堆砌

```python
import time

def login(username, password):
start_time = time.time() # 第1处:记录开始时间
print(f'登录函数开始执行')
# 模拟登录逻辑
time.sleep(0.5)
print(f'登录成功: {username}')
end_time = time.time() # 第2处:记录结束时间
print(f'登录函数执行耗时: {end_time - start_time:.2f}秒') # 第3处:计算耗时
return True

def register(email, password):
start_time = time.time() # 重复第1处
print(f'注册函数开始执行')
# 模拟注册逻辑
time.sleep(0.8)
print(f'注册成功: {email}')
end_time = time.time() # 重复第2处
print(f'注册函数执行耗时: {end_time - start_time:.2f}秒') # 重复第3处
return True

def query_user(user_id):
start_time = time.time() # 重复第1处
print(f'查询用户函数开始执行')
# 模拟查询逻辑
time.sleep(0.3)
print(f'查询用户成功: {user_id}')
end_time = time.time() # 重复第2处
print(f'查询用户函数执行耗时: {end_time - start_time:.2f}秒') # 重复第3处
return {'id': user_id, 'name': '张三'}
```

大佬写法:一个@符号搞定

```python
import time

def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
print(f'{func.__name__}函数开始执行')
result = func(*args, **kwargs)
end_time = time.time()
print(f'{func.__name__}函数执行耗时: {end_time - start_time:.2f}秒')
return result
return wrapper

@timer
def login(username, password):
time.sleep(0.5)
print(f'登录成功: {username}')
return True

@timer
def register(email, password):
time.sleep(0.8)
print(f'注册成功: {email}')
return True

@timer
def query_user(user_id):
time.sleep(0.3)
print(f'查询用户成功: {user_id}')
return {'id': user_id, 'name': '张三'}
```

阿发说实话

同样的功能,小白写了45行,大佬只写了30行。如果有10个函数需要加计时,小白要写100行,大佬还是30行。这就是装饰器的威力——它把横切关注点(日志、计时、权限校验等)从业务逻辑中分离出来,实现代码复用。

SECTION 02

什么是装饰器?从函数传参说起

要理解装饰器,首先要明白一个Python的核心概念:函数是一等公民。这意味着函数可以作为参数传递,可以作为返回值,可以赋值给变量。

函数可以作为参数传递

```python
def greet(name):
return f'Hello, {name}'

def call_function(func, arg):
return func(arg)

result = call_function(greet, '阿发')
print(result) # 输出: Hello, 阿发
```

函数可以作为返回值

```python
def outer():"""外层函数"""
def inner():"""内层函数"""
print('这是内层函数')
return inner # 返回内层函数,注意没有括号

my_func = outer()
my_func() # 输出: 这是内层函数
```

一句话理解装饰器:装饰器就是一个接收函数作为参数,并返回一个新函数的函数。这个新函数会在原函数执行前后添加额外的逻辑。

SECTION 03

@语法糖的本质:它只是语法糖

很多人觉得@符号很神秘,其实它只是一个语法糖(Syntactic Sugar),让代码更简洁易读而已。

```python
# 写法1:使用@语法糖(推荐)
@timer
def login(username, password):
time.sleep(0.5)
return True

# 写法2:等价的手动调用
def login(username, password):
time.sleep(0.5)
return True

login = timer(login) # 把login函数传给timer,再把返回值重新赋值给login
```

这两种写法完全等价!@timer 就是 login = timer(login) 的简写。理解了这一点,装饰器就不再神秘了。

SECTION 04

不带参数的装饰器:最基础也最常用

不带参数的装饰器是最基础的形式,我们在开场例子中已经看到了。让我们再深入剖析一下它的结构。

不带参数装饰器的标准结构

```python
def decorator(func): # 第1层:接收被装饰的函数
def wrapper(*args, **kwargs): # 第2层:包装函数,接收原函数的参数
# 执行前的逻辑(如日志、计时、权限校验等)
print('函数执行前')

# 调用原函数,保存返回值
result = func(*args, **kwargs)

# 执行后的逻辑(如日志、统计等)
print('函数执行后')

# 返回原函数的返回值
return result

# 返回包装函数
return wrapper
```

关键要点解析

· *args 和 **kwargs:这是Python的可变参数语法。*args接收任意数量的位置参数,**kwargs接收任意数量的关键字参数。这样装饰器就能适配任何函数的参数列表。

· 必须调用原函数:wrapper函数内部必须调用func(*args, **kwargs),否则原函数不会执行。

· 必须返回result:如果原函数有返回值,wrapper必须返回这个结果,否则调用者拿不到返回值。

· 必须返回wrapper:外层函数decorator必须返回wrapper函数对象(不带括号),而不是调用wrapper()。

SECTION 05

带参数的装饰器:多一层包装

有时候我们需要给装饰器本身传递参数。比如一个日志装饰器,我们想指定日志级别(info/warn/error)。这时候就需要带参数的装饰器。

带参数装饰器的标准结构

```python
def decorator_with_args(arg1, arg2): # 第1层:接收装饰器参数
def decorator(func): # 第2层:接收被装饰的函数
def wrapper(*args, **kwargs): # 第3层:包装函数
# 可以使用arg1, arg2这些参数
print(f'装饰器参数: {arg1}, {arg2}')

result = func(*args, **kwargs)

return result
return wrapper
return decorator
```

实际应用:日志级别装饰器

```python
def logger(level='info'):
def decorator(func):
def wrapper(*args, **kwargs):
if level == 'info':
print(f'[INFO] {func.__name__}开始执行')
elif level == 'warn':
print(f'[WARN] {func.__name__}需要注意')
elif level == 'error':
print(f'[ERROR] {func.__name__}可能出错')

result = func(*args, **kwargs)

if level == 'info':
print(f'[INFO] {func.__name__}执行完成')
return result
return wrapper
return decorator

# 使用方式:注意括号不能少
@logger(level='warn')
def risky_operation():
print('执行危险操作')

risky_operation()
# 输出: [WARN] risky_operation需要注意
# 执行危险操作
```

带参数vs不带参数的区别:不带参数的装饰器直接写@decorator,带参数的装饰器必须写@decorator(参数)。带参数的装饰器比不带参数的多一层函数嵌套——最外层接收装饰器参数,中间层接收被装饰函数,最内层是包装函数。

SECTION 06

functools.wraps:最容易踩的坑

这是装饰器最容易踩的坑,没有之一。让我先展示一下问题:

问题:函数元信息丢失

```python
def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f'{func.__name__}耗时: {end_time-start_time:.2f}秒')
return result
return wrapper

@timer
def login(username, password):
"""用户登录函数"""
time.sleep(0.5)
return True

# 查看函数元信息
print(login.__name__) # 输出: wrapper(期望是login)
print(login.__doc__) # 输出: None(期望是"用户登录函数")
```

看到了吗?被装饰后的函数,它的__name__变成了wrapper,__doc__变成了None。这是因为装饰器返回的是wrapper函数,所以原来函数的元信息都丢失了。

解决方案:functools.wraps

```python
import time
from functools import wraps # 必须导入wraps

def timer(func):
@wraps(func) # 在wrapper上应用wraps装饰器
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f'{func.__name__}耗时: {end_time-start_time:.2f}秒')
return result
return wrapper

@timer
def login(username, password):
"""用户登录函数"""
time.sleep(0.5)
return True

# 现在元信息正确了
print(login.__name__) # 输出: login
print(login.__doc__) # 输出: 用户登录函数
```

强制规则:写装饰器时,必须在wrapper函数上使用@functools.wraps(func)。这是Python开发者的共识,也是面试官最爱问的问题之一。

SECTION 07

类装饰器:用类实现装饰器

除了用函数实现装饰器,还可以用类来实现。类装饰器通过__call__方法实现可调用对象。

类装饰器的实现方式

```python
import time
from functools import wraps

class Timer:
def __init__(self, func):
self.func = func
wraps(func)(self) # 同样需要保留元信息

def __call__(self, *args, **kwargs):
start_time = time.time()
result = self.func(*args, **kwargs)
end_time = time.time()
print(f'{self.func.__name__}耗时: {end_time-start_time:.2f}秒')
return result

@Timer
def login(username, password):
"""用户登录函数"""
time.sleep(0.5)
return True

login('test', '123456')
# 输出: login耗时: 0.50秒
```

带参数的类装饰器

```python
class Logger:
def __init__(self, level='info'):
self.level = level # 保存装饰器参数

def __call__(self, func): # 接收被装饰的函数
@wraps(func)
def wrapper(*args, **kwargs):
if self.level == 'info':
print(f'[INFO] {func.__name__}开始执行')
elif self.level == 'error':
print(f'[ERROR] {func.__name__}可能出错')
result = func(*args, **kwargs)
return result
return wrapper

@Logger(level='error')
def risky_operation():
print('执行危险操作')

risky_operation()
# 输出: [ERROR] risky_operation可能出错
# 执行危险操作
```

SECTION 08

实战1:日志记录装饰器

日志记录是装饰器最常见的应用场景之一。在接口测试中,我们经常需要记录每个请求的详细信息。

```python
import logging
from functools import wraps

# 配置logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

def log_request(func):
@wraps(func)
def wrapper(*args, **kwargs):
# 记录请求信息
logger.info(f'开始调用 {func.__name__}')
logger.info(f'参数: args={args}, kwargs={kwargs}')

try:
result = func(*args, **kwargs)
logger.info(f'{func.__name__} 调用成功,返回值: {result}')
return result
except Exception as e:
logger.error(f'{func.__name__} 调用失败: {str(e)}')
raise # 重新抛出异常,不影响原有逻辑

return wrapper

@log_request
def api_login(username, password):
"""登录接口"""
if username == 'admin' and password == '123456':
return {'code': 200, 'token': 'abc123'}
else:
raise ValueError('用户名或密码错误')

# 调用测试
api_login('admin', '123456')
# 输出日志:
# INFO:__main__:开始调用 api_login
# INFO:__main__:参数: args=(), kwargs={'username': 'admin', 'password': '123456'}
# INFO:__main__:api_login 调用成功,返回值: {'code': 200, 'token': 'abc123'}
```

SECTION 09

实战2:重试装饰器(测试必备)

在接口测试中,网络请求偶尔会失败,这时候我们需要重试机制。一个好的重试装饰器可以大大简化测试代码。

```python
import time
from functools import wraps

def retry(max_retries=3, delay=1, backoff=2):
"""
重试装饰器
:param max_retries: 最大重试次数
:param delay: 初始延迟(秒)
:param backoff: 退避因子(每次重试延迟乘以backoff)
"""
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
current_delay = delay
last_exception = None

for attempt in range(1, max_retries + 1):
try:
return func(*args, **kwargs)
except Exception as e:
last_exception = e
print(f'{func.__name__} 第{attempt}次调用失败: {e}')

if attempt < max_retries:
print(f'等待 {current_delay} 秒后重试...')
time.sleep(current_delay)
current_delay *= backoff # 指数退避

# 所有重试都失败了
print(f'{func.__name__} 重试{max_retries}次后仍然失败')
raise last_exception

return wrapper
return decorator

@retry(max_retries=3, delay=1, backoff=2)
def flaky_api():"""不稳定的API,模拟网络波动"""
import random
if random.random() < 0.7: # 70%概率失败
raise ConnectionError('网络超时')
return {'code': 200, 'data': 'success'}

# 调用测试
result = flaky_api()
print(result) # 最终会成功返回
```

指数退避策略:重试装饰器使用指数退避(backoff=2),即每次重试的等待时间是上一次的2倍。这样可以避免在服务繁忙时过度请求,给服务恢复的时间。这是生产环境中重试机制的最佳实践。

SECTION 10

实战3:权限校验装饰器

在测试平台或后台系统中,我们经常需要对接口进行权限校验。装饰器是实现权限控制的优雅方式。

```python
from functools import wraps

def require_permission(required_role):
"""权限校验装饰器"""
def decorator(func):
@wraps(func)
def wrapper(user, *args, **kwargs):
# 检查用户角色
if user.get('role') != required_role:
raise PermissionError(f'用户{user["name"]}没有{required_role}权限')

print(f'用户{user["name"]}通过权限校验')
return func(user, *args, **kwargs)

return wrapper
return decorator

@require_permission('admin')
def delete_user(user, user_id):
"""删除用户(需要管理员权限)"""
print(f'管理员{user["name"]}删除用户: {user_id}')
return True

@require_permission('user')
def view_profile(user):
"""查看个人资料(普通用户即可)"""
print(f'用户{user["name"]}查看个人资料')
return {'name': user['name'], 'email': user['email']}

# 测试
admin_user = {'name': 'admin', 'role': 'admin', 'email': 'admin@test.com'}
normal_user = {'name': 'user', 'role': 'user', 'email': 'user@test.com'}

delete_user(admin_user, 123) # 成功
# view_profile(normal_user) # 成功
# delete_user(normal_user, 123) # 抛出PermissionError
```

SECTION 11

内置装饰器盘点:@property/@staticmethod/@classmethod

Python内置了几个常用的装饰器,它们非常实用,也是面试的高频考点。

@property:把方法变成属性

```python
class User:
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name

@property
def full_name(self):
"""计算全名"""
return f'{self.first_name} {self.last_name}'

user = User('张', '三')
print(user.full_name) # 输出: 张 三(注意没有括号!)
# user.full_name = '李四' # 会报错,因为@property默认只读
```

@staticmethod和@classmethod:静态方法和类方法

```python
class Calculator:
pi = 3.14159

@staticmethod
def add(a, b):
"""静态方法:不需要self或cls参数"""
return a + b

@classmethod
def circle_area(cls, radius):
"""类方法:第一个参数是cls,表示类本身"""
return cls.pi * radius ** 2

# 调用方式
print(Calculator.add(2, 3)) # 输出: 5
print(Calculator.circle_area(5)) # 输出: 78.53975
```

· @staticmethod:不需要实例,也不需要类。它只是一个挂在类上的普通函数。

· @classmethod:第一个参数是cls,可以访问和修改类属性。常用于创建工厂方法。

· @property:把方法变成属性访问,不需要括号调用。可以配合@property.setter实现读写控制。

SECTION 12

面试高频问题:你必须会的

· Q1:装饰器的本质是什么?
装饰器是一个接收函数作为参数并返回新函数的函数。@符号是语法糖,等价于func = decorator(func)。

· Q2:为什么要用functools.wraps?
因为装饰器返回的是wrapper函数,会导致原函数的__name__、__doc__等元信息丢失。@wraps(func)会把原函数的元信息复制到wrapper上。

· Q3:带参数和不带参数的装饰器有什么区别?
不带参数的装饰器直接接收被装饰函数;带参数的装饰器多一层嵌套,最外层接收装饰器参数,中间层接收被装饰函数。

· Q4:装饰器可以装饰类吗?
可以。类装饰器通过__call__方法实现。装饰类时,装饰器接收类作为参数,返回一个新类或修改原类。

· Q5:@staticmethod和@classmethod的区别?
staticmethod不需要self或cls参数,是挂在类上的普通函数;classmethod第一个参数是cls,可以访问类属性,常用于工厂方法。

· Q6:怎么实现一个带参数的装饰器?
需要三层嵌套:最外层接收装饰器参数,中间层接收被装饰函数,最内层是包装函数。或者用类装饰器,__init__接收装饰器参数,__call__接收被装饰函数。

最后

装饰器是Python进阶的核心知识点,也是区分小白和大佬的关键标志。同样的功能,小白写重复代码,大佬用装饰器实现优雅复用。掌握装饰器,不仅能让你的代码更简洁,还能在面试中加分。希望今天的内容能帮你彻底搞懂装饰器,以后遇到需要横切关注点的场景,第一时间想到用装饰器来解决。

关于Python进阶、接口测试、AI测试转型等问题,都可以通过公众号菜单栏添加我微信 testafa 私信交流。需要学习资料也可以私信!

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-08-21 19:13:30 HTTP/2.0 GET : https://f.mffb.com.cn/a/503995.html
  2. 运行时间 : 0.477663s [ 吞吐率:2.09req/s ] 内存消耗:4,729.19kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=19ddf114faa1aab87bbe15befc5e6bd6
  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.000833s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001612s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000825s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000825s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001365s ]
  6. SELECT * FROM `set` [ RunTime:0.000680s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001576s ]
  8. SELECT * FROM `article` WHERE `id` = 503995 LIMIT 1 [ RunTime:0.040069s ]
  9. UPDATE `article` SET `lasttime` = 1787310810 WHERE `id` = 503995 [ RunTime:0.002233s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.000630s ]
  11. SELECT * FROM `article` WHERE `id` < 503995 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001292s ]
  12. SELECT * FROM `article` WHERE `id` > 503995 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.001141s ]
  13. SELECT * FROM `article` WHERE `id` < 503995 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.083441s ]
  14. SELECT * FROM `article` WHERE `id` < 503995 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.056623s ]
  15. SELECT * FROM `article` WHERE `id` < 503995 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.118616s ]
0.481481s