python装饰器(Decorator)

python装饰器(Decorator)python 装饰器 Decorator 装饰器

大家好,欢迎来到IT知识分享网。

python装饰器(Decorator) v1

    1. 简述装饰器
    1. 常见的装饰器
    1. 装饰器的应用
    1. 总结

1. 简述装饰器:

1.1 装饰器的功能

装饰器可以让其他函数或类在不需要做额外代码修改的前提下,在代码运行期间动态增加功能的方式。(运行时,动态的给函数或者类添加功能。)

1.2 装饰器的本质

装饰器本质上是一个接受函数作为参数的可调用对象(通常是函数),并返回一个新的函数对象。这个新的函数对象通常会包装或扩展原始函数的行为。(装饰器本质上是一个python函数或类。)

装饰器的返回值也是一个函数/类对象。

1.3 装饰器的应用

装饰器常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。

1.4 装饰器的语法

装饰器是语法糖:利用更简洁流畅的语法实现更为复杂的功能。

使用@ 函数名/类名 可以实现给绑定函数/类额外功能。

1.5 装饰器的引导

# 将函数存储在变量中 def print_message(message): print(f'send message:{ 
     message}') # 变量名引用函数名 send_message = print_message send_message('Hi, python!') # send message:Hi, python! print(type(send_message), type(print_message)) # <class 'function'> <class 'function'> # 相同的地址 print(id(send_message), id(print_message)) # 28 28 
# 将函数作为参数传递给另外一个函数 def return_message(message): return f'send message:{ 
     message}' def call_message(func, message): print(func(message)) call_message(return_message, 'Hi, python!') # send message:Hi, python! 
# 函数嵌套 def func(outer_message): def print_message(message): print(f'print message:{ 
     message}') return print_message(outer_message) func('Hi, python!') # print message:Hi, python! 
# 闭包 def outer(): def inner(message): print(f'print message:{ 
     message}') return inner send_message = outer() send_message('Hi, python!') # print message:Hi, python! 
# 装饰器 def my_decorator(func): def wrapper(): print('my_decorator_wrapper') func() return wrapper @ my_decorator # 或 @my_decorator def print_message(): print('Hi, python!') print_message() 执行结果: my_decorator_wrapper Hi, python! # 通过函数嵌套实现同样的功能 def my_decorator(func): def wrapper(): print('my_decorator_wrapper') func() return wrapper def print_message(): print('Hi, python!') func = my_decorator(print_message) func() 

2. 常见的装饰器

Python中常见的装饰器:函数装饰器、类装饰器、属性装饰器、方法装饰器。

2.1 函数装饰器是最常见的装饰器:

# 记录函数的执行时间 import time def timer(func): def wrapper(*args, kwargs): startTime = time.time() res = func() endTime = time.time() print(f'执行时间:{ 
     endTime - startTime:.2f}秒') # 计算函数的执行时间 return res return wrapper @ timer def myFunction(): time.sleep(1) print('函数执行完毕') myFunction() 执行结果: 函数执行完毕 执行时间:1.00

2.2 类装饰器

# 为类添加一个name的属性 def addName(cls): cls.name = 'MyClass' # 为类添加属性并赋值 return cls @ addName class MyClass: pass print(MyClass.name) 执行结果: MyClass 

2.3 属性装饰器(装饰类的属性,在不改变原属性定义的情况下,为属性添加一些额外的功能):

# 添加类属性检查功能 def typeCheck(attrType): def decorrator(func): def wrapper(self, value): if not isinstance(value, attrType): # 检测类型(int) raise ValueError(f'属性必须是 { 
     attrType} 类型') func(self, value) return wrapper return decorrator class MyClass: @ typeCheck(int) def setValue(self, value): self._value = value myObj = MyClass() myObj.setValue(10) myObj.setValue('python') # 抛出异常 # ValueError: 属性必须是 <class 'int'> 类型 

2.4 方法装饰器(装饰类的方法):

# 为类方法添加缓存 def cache(func): cacheDict = { 
   } # 缓存数据 def wrapper(self, *args): key = (func.__name__, args) if key in cacheDict: print('从缓存中读取数据') return cacheDict[key] print('计算结果并缓存') res = func(self, *args) cacheDict[key] = res return res return wrapper class MyClass: @cache def getValue(self, x): return x  2 myObj = MyClass() print(myObj.getValue(2)) print(myObj.getValue(2)) 执行结果: 计算结果并缓存 4 从缓存中读取数据 4 

2.5 python常见的内部装饰器:

2.5.1静态方法装饰器@staticmethod

静态方法是一种特殊类型的方法,它不需要特殊的第一个参数(如实例方法需要self或类方法需要cls)。静态方法可以通过在方法定义前加上@staticmethod装饰器来创建。

class MyClass: @staticmethod def my_static_method(arg1, arg2): """这是一个静态方法,它不接受特殊的第一个参数。""" return arg1 + arg2 def my_instance_method(self, arg1): """这是一个实例方法,它接受'self'作为第一个参数。""" return self.my_static_method(arg1, 10) # 使用静态方法  result = MyClass.my_static_method(5, 7) print(result) # 输出:12  # 创建类的实例并使用实例方法  instance = MyClass() result_instance = instance.my_instance_method(3) print(result_instance) # 输出:13 

静态方法在功能上类似于模块级别的函数,但是它们被包含在类的命名空间中,这有助于组织代码并提供一种将相关函数分组的方式。静态方法通常用于执行与类无关的操作,这些操作不需要访问或修改类的状态。

值得注意的是,静态方法也可以被类的实例调用,但是它们不会接收到实例引用作为第一个参数,因此它们不能访问或修改实例的状态。如果需要在静态方法中访问类级别的状态,可以显式地传递类名或使用MyClass.前缀来引用类属性。

2.5.2 类方法装饰器@classmethod

类方法是一种特殊类型的方法,它使用@classmethod装饰器来定义,并且第一个参数总是类本身,通常用cls作为参数名。类方法可以在不创建类实例的情况下调用,并且可以访问和修改类级别的状态。

class MyClass: class_variable = "I am a class variable" @classmethod def my_class_method(cls, arg1): """这是一个类方法,它接受'cls'作为第一个参数,可以访问和修改类变量。""" print(cls.class_variable) cls.class_variable = "Class variable has been changed" return arg1 * 2 # 使用类方法  result = MyClass.my_class_method(5) print(result) # 输出:10  # 检查类变量是否已被修改  print(MyClass.class_variable) # 输出:Class variable has been changed  # 创建类的实例并调用类方法  instance = MyClass() print(instance.class_variable) # 输出:Class variable has been changed instance_result = instance.my_class_method(3) print(instance_result) # 输出:6  print(instance.class_variable) # 输出:Class variable has been changed MyClass.class_variable = 'I am a class variable' print(MyClass.class_variable) # 输出:I am a class variable print(instance.class_variable) # 输出:I am a class variable instance.class_variable = 'instance.class_variable' print(MyClass.class_variable) # 输出:I am a class variable print(instance.class_variable) # 输出:instance.class_variable 

类方法通常用于执行与类相关但不依赖于特定实例的操作,例如工厂方法模式、修改类级别的状态或访问类级别的配置。它们也可以在元类编程中非常有用,因为它们可以修改类的定义。

要注意的是,尽管类方法可以通过实例调用,但它们仍然接收类本身作为第一个参数,而不是实例。如果你需要在方法中访问实例状态,那么应该使用实例方法。

2.5.3 描述符装饰器@property

它用于将一个方法变成属性调用的形式。在类定义中,可以使用 @property 装饰器来定义 getter 方法,允许像访问数据属性一样访问方法。setter 方法装饰器@<property_name>.setter。deleter 方法装饰器@<property_name>.deleter。

class Circle: def __init__(self, radius): self._radius = radius @property def radius(self): """Getter for radius.""" return self._radius @radius.setter def radius(self, value): """Setter for radius.""" if value < 0: raise ValueError("Radius cannot be negative!") self._radius = value @radius.deleter def radius(self): del self._radius @property def diameter(self): """Compute the diameter based on the radius.""" return 2 * self._radius # 使用 @property 装饰器  circle = Circle(5) print(circle.radius) # 输出:5,调用了 getter 方法  # 尝试设置 radius 属性  circle.radius = 10 # 调用了 setter 方法  print(circle.radius) # 输出:10  # 尝试获取 diameter 属性  print(circle.diameter) # 输出:20,调用了 diameter 的 getter 方法  # 尝试删除 radius 属性(没有定义 deleter,将会引发 AttributeError)  # del circle.radius  

radius 是一个带有 getter 和 setter 方法的属性。你可以像访问普通属性一样访问它,但实际上是在调用方法。diameter 是一个只有 getter 方法的属性,所以它是只读的。

使用 @property 装饰器的好处是,你可以在不改变代码调用方式的情况下,轻松地添加额外的逻辑到属性的访问和修改过程中。可以在 setter 方法中添加验证逻辑,或者在 getter 方法中添加缓存逻辑。

2.5.4 抽象方法装饰器(abc.abstractmethod)@abstractmethod

它用于指示一个方法是抽象的,即这个方法在抽象基类中不应该有具体的实现。子类在继承这个抽象基类时,必须提供这个抽象方法的具体实现。如果没有实现,子类也将被视为抽象类,不能被直接实例化。@abstractmethod 是 Python 的 abc(抽象基类)模块中的一个装饰器。

from abc import ABC, abstractmethod class Shape(ABC): @abstractmethod def area(self): """计算形状的面积""" pass @abstractmethod def perimeter(self): """计算形状的周长""" pass # 一个遵循 Shape 接口的具体类  class Circle(Shape): def __init__(self, radius): self.radius = radius def area(self): return 3.14159 * (self.radius  2) def perimeter(self): return 2 * 3.14159 * self.radius # 另一个遵循 Shape 接口的具体类  class Rectangle(Shape): def __init__(self, width, height): self.width = width self.height = height def area(self): return self.width * self.height def perimeter(self): return 2 * (self.width + self.height) # 尝试实例化抽象基类 Shape 会引发 TypeError  # shape = Shape()  # 实例化具体类 Circle 和 Rectangle 是可以的  circle = Circle(5) print(circle.area()) # 输出:78.53975  print(circle.perimeter()) # 输出:31.4159  rectangle = Rectangle(4, 6) print(rectangle.area()) # 输出:24  print(rectangle.perimeter()) # 输出:20 

Shape 是一个抽象基类,它定义了两个抽象方法 area 和 perimeter。Circle 和 Rectangle 是 Shape 的子类,它们分别实现了这两个方法。如果你尝试直接实例化 Shape 类,Python 会抛出一个 TypeError,因为 Shape 是一个抽象基类,不能被直接实例化。

使用 @abstractmethod 可以确保你的代码更加健壮,因为它强制要求子类提供必要的方法实现。

3. 装饰器的应用

装饰器的应用:函数装饰函数、函数装饰类、类装饰函数、类装饰类。

# 函数装饰函数 import functools def outer(func): @functools.wraps(func) # 用于保存被装饰的类或函数名 def wrapper(*args, kwargs): print('wrapper') return func(*args, kwargs) return wrapper @outer def func(): pass func() # wrapper 
# 函数装饰类 def outer(cls): @functools.wraps(cls) def wrapper(*args, kwargs): print('wrapper') return cls(*args, kwargs) return wrapper @outer class Foo: pass f = Foo() # wrapper 
# 类装饰函数:定义一个类装饰器,装饰函数,默认调用__call__方法 class Wrap: def __init__(self, func): self._func = func def __call__(self, *args, kwargs): # 类装饰器要实现__call__方法 print('Wrap', self._func.__name__) return self._func(*args, kwargs) @Wrap def func(): pass func() # Wrap func # 通过类方法实现装饰器 class Wrap: def wrapFunc(self): print('wrapFunc') return self @Wrap.wrapFunc def func(): pass func() # wrapFunc # 带计数的装饰器 class Count: def __init__(self, func): self.func = func self.num_calls = 0 def __call__(self, *args, kwargs): self.num_calls += 1 print(f'num of calls is:{ 
     self.num_calls}') return self.func(*args, kwargs) @Count # 等价于example = Count(example) def example(): print('Hi, python!') example() 执行结果: num of calls is:1 Hi, python! example() 执行结果: num of calls is:2 Hi, python! 
# 类装饰类 class Wrap: def __init__(self, cls): self._cls = cls def __call__(self, *args, kwargs): print('Wrap') return self._cls(*args, kwargs) @Wrap class C: pass c = C() 
# 装饰器通用示例 import functools def my_decorator(func): # 保留原函数的元信息(原函数的元信息拷贝到对应的装饰器函数里) @functools.wraps(func) def wrapper(*args, kwargs): print("Before calling the function") result = func(*args, kwargs) print("After calling the function") return result return wrapper # 在使用装饰器的时候名字才会被替换,add.__name__就会变成wrapper。使用functools.wraps(func)保存元信息。 @my_decorator def add(x, y): return x + y print(add.__name__) # add ''' 如果不使用@functools.wraps(func) print(add.__name__) # wrapper ''' 

带参数的装饰器:

# 带参数的函数装饰器(在增加一层嵌套) def repeat(num): # 接收装饰器参数,@repeat(3) def my_decorator(func): # 接收装饰器函数/类名 @functools.wraps(func) # 接收要执行函数参数,print_message(*args, kwargs) def wrapper(*args, kwargs): for i in range(num): func(*args, kwargs) return wrapper return my_decorator @repeat(3) # 传入循环执行的次数 def print_message(): print('Hi, python!') print_message() print(print_message.__name__) 执行结果: Hi, python! Hi, python! Hi, python! print_message 
# 带参数的类装饰器 class Count: # 接收装饰器的参数,Count(*args,kwargs) def __init__(self, *args, kwargs): self.args = args self.kwargs = kwargs self.num_calls = 0 def __call__(self, func): # 接收函数或类名 @functools.wraps(func) # 接收要装饰的函数或类的参数,example(*args, kwargs) def wrapper(*args, kwargs): print('self.args:', self.args) print('self.kwargs:', self.kwargs) self.num_calls += 1 print(f'num of calls is:{ 
     self.num_calls}') return func(*args, kwargs) return wrapper @Count('aaa') def example(): print('Hi, python!') example() print(example.__name__) 执行结果: self.args: ('aaa',) self.kwargs: { 
   } num of calls is:1 Hi, python! example 
# 描述符装饰器 class MyClass: @property def value(self): print('MyClass().value') @value.setter def value(self, message): print(message) obj = MyClass() obj.value # MyClass().value obj.value = 'Hi, python!' # Hi, python! obj.value # MyClass().value # 等价于: class MyClass: def get_value(self): print('MyClass().value') def set_value(self, message): print(message) def del_value(self): pass value = property(get_value, set_value, del_value, 'value...') obj = MyClass() obj.value # MyClass().value obj.value = 'Hi, python!' # Hi, python! obj.value # MyClass().value print('doc:', MyClass.value.__doc__) # doc: value... 
# 自定义实现描述符装饰器(__get__()、__set__()、__delete__()) class MyProperty: def __init__(self, func): self.func = func self.name = func.__name__ self.cache = { 
   } # 缓存装饰器 def __get__(self, instance, owner): if instance is None: return self if self.name not in self.cache: value = self.func(instance) print('value:', value) print('self.cache:', self.cache) self.cache[self.name] = value print('self.cache:', self.cache) return self.cache[self.name] def __set__(self, instance, value): print(value) self.cache[self.name] = value class MyClass: @MyProperty def value(self): print('MyClass().v`alue') print('--'*5) obj = MyClass() obj.value # MyClass().value # 修改了value的指向,self.cache[self.name] obj.value = 'Hi, python!' # Hi, python!  print(obj.value) # Hi, python! # print(obj.zz) # AttributeError: 'MyClass' object has no attribute 'zz' 执行结果: ---------- MyClass().value value: None self.cache: { 
   } self.cache: { 
   'value': None} Hi, python! Hi, python! print('--'*5) obj1 = MyClass() obj1.value # 从缓存取数据self.cache print(obj1.value) # Hi, python! obj1.value = 'obj1.value' # obj1.value print(obj.value) # obj1.value (从缓存取数据,self.cache) 执行结果: ---------- Hi, python! obj1.value obj1.value 
# 装饰类的装饰器 (输入是类,输出也是类) import time # timer_decorator装饰器接收一个类作为参数,并返回一个继承自原始类的新类TimerClass。TimerClass中重写了__getattribute__方法,在调用类的方法时,会计算方法的执行时间并进行打印。 def timer_decorator(cls): class TimerClass(cls): def __getattribute__(self, item): attribute = object.__getattribute__(self, item) if callable(attribute): def wrapped_method(*args, kwargs): start_time = time.time() result = attribute(*args, kwargs) end_time = time.time() execution_time = end_time - start_time print(f'Method { 
     item} exectued in { 
     execution_time} sec-onds.') return result return wrapped_method else: return attribute return TimerClass @timer_decorator class MyClass: def my_method(self): time.sleep(2) print('Executing my_method') @timer_decorator class MyClass1: def my_method(self): time.sleep(2) print('Executing my_method') def print_message(self): print('message') obj = MyClass() obj.my_method() obj = MyClass1() obj.my_method() obj.print_message() 输出结果: Executing my_method Method my_method exectued in 2.00695 seconds. Executing my_method Method my_method exectued in 2.00426 seconds. message Method print_message exectued in 0.0 seconds. 
# functools.partial import time import functools class DelayFunc: def __init__(self, duration, func): self.duration = duration self.func = func def __call__(self, *args, kwargs): print(f'Wait for { 
     self.duration} seconds...') time.sleep(self.duration) return self.func(*args, kwargs) def eager_call(self, *args, kwargs): print('Call without delay') return self.func(*args, kwargs) def delay(duration): """装饰器:推迟某个函数的执行。同时提供 .eager_call 方法立即执行 """ # 此处为了避免定义额外函数,直接使用 functools.partial 帮助构造 # DelayFunc 实例 return functools.partial(DelayFunc, duration) @delay(duration=2) def add(a, b): return a + b # 这次调用将会延迟 2 秒 res = add(1, 2) print(res) # 这次调用将会立即执行 res = add.eager_call(1, 2) print(res) 执行结果: Wait for 2 seconds... 3 Call without delay 3 
# 返回值指向其他函数的装饰器 def func1(): print('func1') def func2(func): return func1 @func2 def func3(): print('func3') func3() # func1 # 不会执行func3里面的print() 
# 装饰器的嵌套 import functools def my_decorator1(func): @functools.wraps(func) def wrapper(*args, kwargs): print('execute decorator1') result = func(*args, kwargs) print('end execute decorator1') return result return wrapper def my_decorator2(func): @functools.wraps(func) def wrapper(*args, kwargs): print('execute decorator2') result = func(*args, kwargs) print('end execute decorator2') return result return wrapper @my_decorator1 @my_decorator2 def print_message(message): print(message) print_message('Hi, Python!') 执行结果: execute decorator1 execute decorator2 Hi, Python! end execute decorator2 end execute decorator1 装饰器执行的嵌套顺序:从内到外定义,从外到内执行。 # 嵌套装饰器的执行顺序 def outer_decorator(func): def wrapper(): print('执行顺序1') func() print('执行顺序4') return 2 return wrapper def inner_decorator(func): def wrapper(): print('执行顺序2') func() print('执行顺序3') return 1 return wrapper @outer_decorator @inner_decorator def my_function(): print("Function is being called") my_function() 执行结果: 执行顺序1 执行顺序2 Function is being called 执行顺序3 执行顺序4 

函数引用装饰器内的属性:

class fun: funA = 10 funB = 20 def __init__(self, func): self.func = func self.funa = 'funaaaaa' def __call__(self, *args, kwargs): self.funb = 'funbbbbb' print('fun__call__') result = self.func(*args, kwargs) return result @fun def f(): """函数引用装饰器内的属性""" print(f.funa) print(f.funb) print("f") print('---f') f() 执行结果: ---f fun__call__ funaaaaa funbbbbb f 
  • 简单的电商案例
# 电商领域有个功能明显可以使用“策略”模式,即根据客户的属性或订单中的商品计算折扣。 # 有1000或以上积分的顾客,每个订单享5% 折扣。 # 同一订单中,单个商品的数量达到20个或以上,享10%折扣。 # 订单中的不同商品达到10个或以上,享7%折扣。 # 假定一个订单一次只能享用一个折扣。 from collections import namedtuple promos = [] def promotion(promo_func): promos.append(promo_func) return promo_func @promotion def fidelity(order): """为积分为1000或以上的顾客提供5%折扣""" return order.total() * .5 if order.customer.fidelity >= 1000 else 0 @promotion def bulk_item(order): """单个商品为20个或以上时提供10%折扣""" discount = 0 for item in order.cart: if item.quantity >= 20: discount += item.total() * .1 return discount @promotion def large_order(order): """订单中的不同商品达到10个或以上时提供7%折扣""" distinct_items = { 
   item.product for item in order.cart} if len(distinct_items) >= 10: return order.total() * .07 return 0 def best_promo(order): """选择可用的最佳折扣""" return max(promo(order) for promo in promos) Customer = namedtuple('Customer', 'name fidelity') class LineItem: def __init__(self, product, quantity, price): self.product = product self.quantity = quantity self.price = price def total(self): return self.price * self.quantity class Order: def __init__(self, customer, cart, promotions=None): self.__total = None self.customer = customer self.cart = list(cart) self.promotion = promotions def total(self): if not hasattr(self, '__total'): # LineItem.total() self.__total = sum(item.total() for item in self.cart) return self.__total joe = Customer('John Doe', 1000) # 积分为1000 joe_cart = [LineItem('banana', 4, 5.0), LineItem('apple', 10, 1.5), LineI-tem('watermellon', 5, 5.0)] joe_order = Order(joe, joe_cart) print(best_promo(joe_order)) # 30.0 (20+15+25)*0.5 

4. 总结

装饰器(Decorator)是 Python 中的一个高级功能,允许你修改或增强函数、方法或类的行为,而不需要修改它们的源代码。装饰器本质上是一个接受函数作为参数的可调用对象(通常是一个函数),并返回一个新的函数对象。这个新的函数对象通常会包装(wrap)或修改原始函数的行为。

  • 语法:
    • 使用 @decorator_name 语法将装饰器应用于函数、方法或类。
    • 装饰器可以应用于定义之前或之后的函数,但通常放在函数定义之前。
  • 工作原理
    • 当 Python 解释器遇到被装饰的函数时,它会立即执行装饰器函数,并将被装饰的函数作为参数传递给装饰器函数。
    • 装饰器函数返回一个“包装器”(wrapper)函数,这个包装器函数通常在被装饰的函数之前和/或之后执行某些操作,然后调用原始函数。
    • 原始函数的名称和文档字符串(如果有的话)通常会被复制到包装器函数中,以保持函数的身份不变。
  • 用途
    • 日志记录:在函数调用前后记录日志信息。
    • 性能测试:测量函数执行的时间。
    • 缓存:缓存函数的结果,避免重复计算。
    • 权限校验:在访问特定函数之前检查用户权限。
    • 事务管理:确保一系列操作要么全部成功,要么全部失败。
    • 函数参数校验:在函数调用前验证参数。
  • 嵌套装饰器:
    • 可以将多个装饰器应用于同一个函数。这通常是通过将多个装饰器函数依次应用于函数来实现的。
    • 嵌套装饰器的执行顺序是从内到外(即靠近函数定义的装饰器先执行),但装饰器函数本身的调用顺序是从外到内。
  • 类装饰器:
    • 除了函数可以作为装饰器之外,类也可以作为装饰器。
    • 当类被用作装饰器时,Python 会调用类的 call 方法来执行装饰操作。
  • 注意事项:
    • 装饰器可能会增加代码的复杂性,因此应该谨慎使用。
    • 如果装饰器改变了函数的行为,这可能会使代码更难理解和维护。
    • 使用装饰器时要确保它们不会引入意外的副作用或性能问题。
  • 使用场景:
    • 当你想要在不修改原始函数源代码的情况下增强函数功能时,装饰器是一个很好的选择。
    • 在设计框架或库时,装饰器可以作为一种灵活的方式来扩展功能或修改行为。
  • 示例:
    def my_decorator(func): def wrapper(): print("Something is happening before the function is called.") func() print("Something is happening after the function is called.") return wrapper @my_decorator def say_hello(): print("Hello!") say_hello() 执行结果: Something is happening before the function is called. Hello! Something is happening after the function is called. 

一切callable的对象都可以被用来实现装饰器。

装饰器执行的嵌套顺序:从内到外定义,从外到内执行。

使用装饰器感到迷茫的时候,可以将装饰器用等价的形式转换。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/112203.html

(0)
上一篇 2026-01-20 07:15
下一篇 2026-01-20 07:26

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信