全网最新最全面的python学习总结,涵盖常用的大部分内容(2

22 # 使用locals()函数可以访问局部作用域。
23 def func():
24 x = 2
25 print(locals()[“x”])
26
27 func()
28
29 # 每个函数定义时都会记住所在的作用域。
30 # 函数执行的时候会开启一个新的作用域,函数内变量访问的规则是:先访问当前作用域,如果没有就访问函数定义时的作用域,递归直到全局作用域。
31 x = 1
32
33 def func():
34 y = 2
35 print(x, y) # 输出1 2
36
37 func()
38
39
40 # 变量赋值始终访问的是当前作用域。
41 x = 1
42
43 def func():
44 x = 2
45 y = 2
46 print(x, y) # 输出2 2
47
48 func()
49 print(x) #输出 1
50
51 # 局部变量会覆盖隐藏全局变量,想访问全局变量可以采用global关键字或globals()函数。
52 x = 1
53
54 def func():
55 global x
56 x = 2
57 y = 2
58 print(x, y) # 输出2 2
59
60 func()
61 print(x) #输出 2



1 # python支持闭包
2 def func(x):
3 def inner_func(y):
4 print(x + y)
5
6 return inner_func
7
8 inner_func = func(10)
9 inner_func(1)
10 inner_func(2)



1 #函数作为对象
2 def func(fn, arg):
3 fn(arg)
4
5 func(print, “hello”)
6 func(lambda arg : print(arg), “hello”)


## 五.模块


几个模块相关的规则:


* 一个文件代表一个模块。
* 可以用import module导入模块,也可以用form module import member导入模块的成员。
* 如果导入的是module,必须使用module.member进行访问;如果导入的member,可以直接访问member。
* 导入的module或member都会变成当前module的member。


b.py



1 # coding=utf-8
2
3 print name
4
5 def say_b():
6 print “b”


a.py



1 # coding=utf-8
2
3 import b
4 from b import *
5
6 print name
7
8 def say_a():
9 print “a”


test.py



1 # coding=utf-8
2
3 import a
4
5 print name
6
7 a.say_a();
8 a.say_b();
9 a.b.say_b()


输出



1 b
2 a
3 main
4 a
5 b
6 b


## 六.异常管理



1 # coding=utf-8
2
3 # 自定义异常
4 class HappyException(Exception):
5 pass
6
7 # 引发和捕获异常
8 try:
9 raise HappyException
10 except:
11 print(“HappyException”)
12
13 try:
14 raise HappyException()
15 except:
16 print(“HappyException”)
17
18 # 捕获多种异常
19 try:
20 raise HappyException
21 except (HappyException, TypeError):
22 print(“HappyException”)
23
24 # 重新引发异常
25 try:
26 try:
27 raise HappyException
28 except (HappyException, TypeError):
29 raise
30 except:
31 print(“HappyException”)
32
33 #访问异常实例
34 try:
35 raise HappyException(“都是我的错”)
36 except (HappyException, TypeError), e:
37 print(e)
38
39 #按类型捕获
40 try:
41 raise HappyException
42 except HappyException:
43 print(“HappyException”)
44 except TypeError:
45 print(“TypeError”)
46
47 #全面捕获
48 try:
49 raise HappyException
50 except:
51 print(“HappyException”)
52
53 #没有异常的else
54 try:
55 pass
56 except:
57 print(“HappyException”)
58 else:
59 print(“没有异常”)
60
61 #总会执行的final
62 try:
63 pass
64 except:
65 print(“HappyException”)
66 else:
67 print(“没有异常”)
68 finally:
69 print(“总会执行”)


## 七.面向对象


### **7.1先上一张图**


![](https://img-blog.csdnimg.cn/img_convert/6670b93f51b34506772397dd7f9b3276.png)


### **7.2几个规则:**


1. 一切都是对象,python中一切都是对象,每个对象都包含一个\_\_class\_\_属性以标记其所属类型。
2. 每个对象(记得一切都是对象啊)都包含一个\_\_dict\_\_属性以存储所有属性和方法。
3. 每个类型都包含一个\_\_bases\_\_属性以标记其父类。
4. 属性和方法的访问规则:依次搜索instance、子类、父类、父类的父类、直到object的\_\_dict\_\_,如果找到就返回。
5. 属性和方法的设置规则:直接设置instance.\_\_dict\_\_。
6. 以上属性和方法访问或设置规则没有考虑“魔法方法”,下文会解释。


### **7.3 示例**



1 # coding=utf-8
2
3 metaclass = type
4
5 # 类型定义
6 # 实例方法必的第一个参数代表类型实例,类似其他语言的this。
7 class Animal:
8 name = “未知” # 属性定义。
9
10 def init(self, name): #构造方法定义。
11 self.name = name
12
13 def getName(self): # 实例方法定义。
14 return self.name
15
16 def setName(self, value):
17 self.name = value
18
19 print(Animal.name) # 未知
20 print(Animal.dict[“name”]) # 未知
21
22 animal = Animal(“狗狗”)
23 print(animal.name) # 狗狗
24 print(animal.dict[“name”]) # 狗狗
25 print(Animal.name) # 未知
26 print(Animal.dict[“name”]) # 未知
27 print(animal.class.name) # 未知
28 print(animal.class.dict[“name”]) # 未知



1 # 类型定义中的代码会执行,是一个独立的作用域。
2 class TestClass:
3 print(“类型定义中”) #类型定义中


### **7.4绑定方法和未绑定方法**



1 class TestClass:
2 def method(self):
3 print(“测试方法”)
4
5 test = TestClass()
6 print(TestClass.method) #


绑定方法已经绑定了对象示例,调用的时刻不用也不能传入self参数了。


注:使用对象访问实例方法为何会返回绑定方法?这个还得等到学完“魔法方法”才能解释,内部其实是拦截对方法成员的访问,返回了一个Callable对象。


### **7.5私有成员**



1 # 私有成员
2 class TestClass:
3 __private_property = 1
4
5 def __private_method():
6 pass
7
8 print(TestClass.dict) # {‘module’: ‘main’, ‘_TestClass__private_method’: <function __private_method at 0x0212B970>, ‘_TestClass__private_property’: 1


难怪访问不了了,名称已经被修改了,增加了访问的难度而已。


### **7.6多重继承**



1 #多重继承
2 class Base1:
3 pass
4
5 class Base2:
6 pass
7
8 class Child(Base2, Base1):
9 pass
10
11 child = Child()
12 print(isinstance(child, Child)) # True
13 print(isinstance(child, Base2)) # True
14 print(isinstance(child, Base1)) # True


如果继承的多个类型之间有重名的成员,左侧的基类优先级要高,上例子Base2会胜出。


### **7.7接口那里去了,鸭子类型比接口更好用。**



1 class TestClass1:
2 def say(self):
3 print(“我是鸭子1”)
4
5 class TestClass2:
6 def say(self):
7 print(“我是鸭子2”)
8
9 def duck_say(duck):
10 duck.say()
11
12 duck_say(TestClass1()) # 我是鸭子1
13 duck_say(TestClass2()) # 我是鸭子2


### **7.8调用父类**



1 # 调用父类
2 class Base:
3 def say(self):
4 print(“Base”)
5
6 class Child(Base):
7 def say(self):
8 Base.say(self)
9 super(Child, self).say()
10 print(“Child”)
11
12 child = Child()
13 child.say()


## 八.魔法方法


对象构造相关:\_\_new\_\_、\_\_init\_\_、\_\_del\_\_。



1 from os.path import join
2
3 class FileObject:
4 ‘’‘Wrapper for file objects to make sure the file gets closed on deletion.’‘’
5
6 def init(self, filepath=‘~’, filename=‘sample.txt’):
7 # open a file filename in filepath in read and write mode
8 self.file = open(join(filepath, filename), ‘r+’)
9
10 def del(self):
11 self.file.close()
12 del self.file


运算符重载:所有运算符都能重载。



1 class Word(str):
2 ‘’‘Class for words, defining comparison based on word length.’‘’
3
4 def new(cls, word):
5 # Note that we have to use new. This is because str is an immutable
6 # type, so we have to initialize it early (at creation)
7 if ’ ’ in word:
8 print “Value contains spaces. Truncating to first space.”
9 word = word[:word.index(’ ')] # Word is now all chars before first space
10 return str.new(cls, word)
11
12 def gt(self, other):
13 return len(self) > len(other)
14
15 def lt(self, other):
16 return len(self) < len(other)
17
18 def ge(self, other):
19 return len(self) >= len(other)
20
21 def le(self, other):
22 return len(self) <= len(other)
23
24 print(Word(“duan”) > Word(“wei”))


属性访问。



1 class AccessCounter:
2 ‘’‘A class that contains a value and implements an access counter.
3 The counter increments each time the value is changed.’‘’
4
5 def init(self, value):
6 super(AccessCounter, self).setattr(‘counter’, 0)
7 super(AccessCounter, self).setattr(‘value’, value)
8
9 def setattr(self, name, value):
10 if name == ‘value’:
11 super(AccessCounter, self).setattr(‘counter’, self.counter + 1)
12 # Make this unconditional.
13 # If you want to prevent other attributes to be set, raise AttributeError(name)
14 super(AccessCounter, self).setattr(name, value)
15
16 def delattr(self, name):
17 if name == ‘value’:
18 super(AccessCounter, self).setattr(‘counter’, self.counter + 1)
19 super(AccessCounter, self).delattr(name)


集合实现。



1 class FunctionalList:
2 ‘’‘A class wrapping a list with some extra functional magic, like head,
3 tail, init, last, drop, and take.’‘’
4
5 def init(self, values=None):
6 if values is None:
7 self.values = []
8 else:
9 self.values = values
10
11 def len(self):
12 return len(self.values)
13
14 def getitem(self, key):
15 # if key is of invalid type or value, the list values will raise the error
16 return self.values[key]
17
18 def setitem(self, key, value):
19 self.values[key] = value
20
21 def delitem(self, key):
22 del self.values[key]
23
24 def iter(self):
25 return iter(self.values)
26
27 def reversed(self):
28 return FunctionalList(reversed(self.values))
29
30 def append(self, value):
31 self.values.append(value)
32 def head(self):
33 # get the first element
34 return self.values[0]
35 def tail(self):
36 # get all elements after the first
37 return self.values[1:]
38 def init(self):
39 # get elements up to the last
40 return self.values[:-1]
41 def last(self):
42 # get last element
43 return self.values[-1]
44 def drop(self, n):
45 # get all elements except first n
46 return self.values[n:]
47 def take(self, n):
48 # get first n elements
49 return self.values[:n]


可调用对象,像方法一样调用对象。



1 class Entity:
2 ‘’‘Class to represent an entity. Callable to update the entity’s position.’‘’
3
4 def init(self, size, x, y):
5 self.x, self.y = x, y
6 self.size = size
7
8 def call(self, x, y):
9 ‘’‘Change the position of the entity.’‘’
10 self.x, self.y = x, y
11 print(x, y)
12
13 entity = Entity(5, 1, 1)
14 entity(2, 2)


资源管理



1 class Closer:
2 def enter(self):
3 return self
4
5 def exit(self, exception_type, exception_val, trace):
6 print(“清理完成”)
7 return True;
8
9 with Closer() as closer:
10 pass


对象描述符。



1 class Meter(object):
2 ‘’‘Descriptor for a meter.’‘’
3
4 def init(self, value=0.0):
5 self.value = float(value)
6 def get(self, instance, owner):
7 return self.value
8 def set(self, instance, value):
9 self.value = float(value)
10
11 class Foot(object):
12 ‘’‘Descriptor for a foot.’‘’
13
14 def get(self, instance, owner):
15 return instance.meter * 3.2808
16 def set(self, instance, value):
17 instance.meter = float(value) / 3.2808
18
19 class Distance(object):
20 ‘’‘Class to represent distance holding two descriptors for feet and
21 meters.’‘’
22 meter = Meter()
23 foot = Foot()


## 九.Mixin(也叫掺入)


### **9.1掺入模块:playable.py**



1 # coding=utf-8
2
3 def paly(self):
4 print(“游戏中…”)


### **9.2掺入目标模块:test.py**



1 # coding=utf-8
2
3 class Animal:
4 from playable import paly
5
6 animal = Animal()
7 animal.paly() # 游戏中…


## 十.Open Class(打开类型,从新定义成员)



1 #coding:utf-8
2
3 class TestClass:
4 def method1(self):
5 print(“方法1”)
6
7 def method2(self):
8 print(“方法2”)
9
10 TestClass.method2 = method2
11
12 test = TestClass()
13 test.method1() # 方法1
14 test.method2() # 方法2


## 十一.Meta Programming(元编程)



1 TestClass = type(“TestClass”, (object,), {
2 “say”: lambda self : print(“你好啊”)
3 })
4
5 test = TestClass()
6 test.say()



1 def getter(name):
2 def getterMethod(self):
3 return self.getattribute(name)
4 return getterMethod
5
6 def setter(name):
7 def setterMethod(self, value):
8 self.setattr(name, value)
9 return setterMethod
10
11 class TestClass:
12 getName = getter(“name”)
13 setName = setter(“name”)
14
15 test = TestClass()
16 test.setName(“段光伟”)
17 print(test.getName())


## 十二.AOP(面向切面编程)


内容比较多:


## 十三.背景


学习了Javascript才知道原来属性的取值和赋值操作访问的“位置”可能不同、还有词法作用域这个东西,这也是我学习任何一门语言会注意的两个知识点,Python的作用域和Javascript几乎一致,这里就不做解释,本文重点介绍一下三个概念:


1. 属性取值和赋值过程
2. 属性描述符
3. 装饰器


本文最好会利用这些知识介绍:如何实现自定义的@staticmethod和@classmethod。


## 十四.属性取值和赋值过程


![](https://img-blog.csdnimg.cn/img_convert/1b01e9f72a42fe6be8ba5024d573aa86.png)


* 一切皆是对象,类型也是对象。
* 对象包含一个\_\_class\_\_属性指向其所属类型。
* 对象包含一个\_\_dict\_\_属性指向其所包含的成员(属性和方法)。


### 14.1取值过程(下面是伪代码)



1 getattribute(property) logic:
2
3 descripter = find first descripter in class and bases’s dict(property)
4 if descripter:
5 return descripter.get(instance, instance.class)
6 else:
7 if value in instance.dict
8 return value
9
10 value = find first value in class and bases’s dict(property)
11 if value is a function:
12 return bounded function(value)
13 else:
14 return value
15
16 raise AttributeNotFundedException


### 14.2赋值过程(下面是伪代码)



1 setattr(property, value)logic:
2
3 descripter = find first descripter in class and bases’s dict(property)
4 if descripter:
5 descripter.set(instance, value)
6 else:
7 instance.dict[property] = value


### 14.3根据取值和赋值过程的逻辑可以得出以下结论


1. 赋值和取值的位置可能不同。
2. 取值过程的伪代码第11行会返回绑定方法(我们在Javascript经常会让某个函数绑定到指定的作用域,和这个概念是一样的)。
3. 取值和赋值过程都会先查找属性描述符,也就是说:属性描述的优先级最高,下文会介绍属性描述符。


## 十五.属性描述符


什么是属性描述符?属性描述符就是一个类型,实现了三个魔法方法而已:\_\_set\_\_、\_\_get\_\_和\_\_del\_\_,属性描述符一般不会独立使用,必须存储在类型的\_\_dict\_\_中才有意义,这样才会参与到属性的取值和赋值过程,具体参见上文。


### **15.1属性描述符**



1 #属性描述符
2 class Descripter:
3 def get(self, instance, owner):
4 print(self, instance, owner)
5
6 def set(self, instance, value):
7 print(self, instance, value)


### **15.2测试代码**



1 class TestClass:
2 Des = Descripter()
3
4
5 def getattribute(self, name):
6 print(“before getattribute”)
7 return super(TestClass, self).getattribute(name)
8 print(“after getattribute”)
9
10 def setattr(self, name, value):
11 print(“before setattr”)
12 super(TestClass, self).setattr(name, value)
13 print(“after setattr”)
14
15 test1 = TestClass()
16 test2 = TestClass()
17
18 test1.Des = None
19 test2.Des


### **15.3输出结果**



1 before setattr
2 <main.Descripter object at 0x01D9A030> <main.TestClass object at 0x01D9A090> None
3 after setattr
4 before getattribute
5 <main.Descripter object at 0x01D9A030> <main.TestClass object at 0x01D9A0B0> <class ‘main.TestClass’>


### **15.4结论**


类型的多个实例共享同一个属性描述符实例,属性描述符的优先级高于实例的\_\_dict\_\_,具体自己可以测试一下。


## 十六.装饰器(AOP)


### **16.1最基本的函数装饰器**



1 print(“\n最基本的函数装饰器\n”)
2 def log(fun):
3 def return_fun(*args, **kargs):
4 print(“开始输出日志”)
5
6 fun(*args, **kargs)
7
8 print(“结束输出日志”)
9
10 return return_fun
11
12 @log
13 def say(message):
14 print(message)
15
16 say(“段光伟”)
17
18 print(“\n等价方法\n”)
19
20 def say(message):
21 print(message)
22
23 say = log(say)
24 say(“段光伟”)


### **16.2带参数的函数装饰器**



1 print(“\n带参数的函数装饰器\n”)
2 def log(header, footer):
3 def log_to_return(fun):
4 def return_fun(*args, **kargs):
5 print(header)
6
7 fun(*args, **kargs)
8
9 print(footer)
10
11 return return_fun
12 return log_to_return
13
14 @log(“开始输出日志”, “结束输出日志”)
15 def say(message):
16 print(message)
17
18 say(“段光伟”)
19
20 print(“\n等价方法\n”)
21
22 def say(message):
23 print(message)
24
25 say = log(“开始输出日志”, “结束输出日志”)(say)
26 say(“段光伟”)


### **16.3最基本的类型装饰器**



1 print(“\n最基本的类型装饰器\n”)
2 def flyable(cls):
3 def fly(self):
4 print(“我要飞的更高”)
5 cls.fly = fly
6
7 return cls
8
9 @flyable
10 class Man:
11 pass
12
13 man = Man()
14 man.fly()
15
16 print(“\n等价方法\n”)
17
18 class Man:
19 pass
20
21 Man = flyable(Man)
22
23 man = Man()
24 man.fly()


### **16.4带参数的类型装饰器**



1 print(“\n带参数的类型装饰器\n”)
2 def flyable(message):
3 def flyable_to_return(cls):
4 def fly(self):
5 print(message)
6 cls.fly = fly
7
8 return cls
9 return flyable_to_return
10
11 @flyable(“我要飞的更高”)
12 class Man:
13 pass
14
15 man = Man()
16 man.fly()
17
18 print(“\n等价方法\n”)
19
20 class Man:
21 pass
22
23 Man = flyable(“我要飞的更高”)(Man)
24
25 man = Man()
26 man.fly()


备注:可以使用多个装饰器,不过要保证签名的装饰器也是返回的一个方法或类型。


## 十七.自己实现@staticmethod和@classmethod


理解了属性的取值和赋值过程,开发自定义@staticmethod和@classmethod就不成问题了,let up do it!


**17.1代码**



1 class MyStaticObject:
2 def init(self, fun):
3 self.fun = fun;
4
5 def get(self, instance, owner):
6 return self.fun
7
8 def my_static_method(fun):
9 return MyStaticObject(fun)
10
11 class MyClassObject:
12 def init(self, fun):
13 self.fun = fun;
14
15 def get(self, instance, owner):
16 def class_method(*args, **kargs):
17 return self.fun(owner, *args, **kargs)
18
19 return class_method
20
21 def my_class_method(fun):
22 return MyClassObject(fun)
23
24 class C(object):
25 “”“docstring for C”“”
26
27 def test_instance_method(self):
28 print(self)
29
30 @staticmethod
31 def test_static_method(message):
32 print(message)
33
34 @my_static_method
35 def test_my_static_method(message):
36 print(message)
37
38 @classmethod
39 def test_class_method(cls):
40 print(cls)
41
42 @my_class_method
43 def test_my_class_method(cls):
44 print(cls)
45
46 print(“\n实例方法测试”)
47 c = C()
48 print(C.test_instance_method)
49 print(C.dict[“test_instance_method”])
50 print(c.test_instance_method)
51 C.test_instance_method©
52 c.test_instance_method()
53
54 print(“\n静态方法测试”)
55 print(C.test_static_method)
56 print(C.dict[“test_static_method”])
57 print(c.test_static_method)
58 C.test_static_method(“静态方法测试”)
59 c.test_static_method(“静态方法测试”)
60
61 print(“\n自定义静态方法测试”)
62 print(C.test_my_static_method)
63 print(C.dict[“test_my_static_method”])
64 print(c.test_my_static_method)
65 C.test_my_static_method(“自定义静态方法测试”)
66 c.test_my_static_method(“自定义静态方法测试”)
67
68 print(“\n类方法测试”)
69 print(C.test_class_method)
70 print(C.dict[“test_class_method”])
71 print(c.test_class_method)
72 C.test_class_method()
73 c.test_class_method()
74
75 print(“\n自定义类方法测试”)
76 print(C.test_my_class_method)
77 print(C.dict[“test_my_class_method”])
78 print(c.test_my_class_method)
79
80 C.test_my_class_method()
81 c.test_my_class_method()
82
83 print(“\n对象上的方法不会返回绑定方法,对象描述符也不会起作用”)
84 def test(self):
85 print(self)
86
87 c.test = test
88
89 c.test(“测试”)


### **17.2结果**



1 实例方法测试
2 <function C.test_instance_method at 0x01D3D8A0>
3 <function C.test_instance_method at 0x01D3D8A0>
4 <bound method C.test_instance_method of <main.C object at 0x01D8B5B0>>
5 <main.C object at 0x01D8B5B0>
6 <main.C object at 0x01D8B5B0>
7
8 静态方法测试
9 <function C.test_static_method at 0x01D69108>
10 <staticmethod object at 0x01D8B4F0>
11 <function C.test_static_method at 0x01D69108>
12 静态方法测试
13 静态方法测试
14
15 自定义静态方法测试
16 <function C.test_my_static_method at 0x01D69078>
17 <main.MyStaticObject object at 0x01D8B510>
18 <function C.test_my_static_method at 0x01D69078>
19 自定义静态方法测试
20 自定义静态方法测试
21
22 类方法测试
23 <bound method type.test_class_method of <class ‘main.C’>>
24 <classmethod object at 0x01D8B530>
25 <bound method type.test_class_method of <class ‘main.C’>>
26 <class ‘main.C’>
27 <class ‘main.C’>
28
29 自定义类方法测试
30 <function MyClassObject.get..class_method at 0x01D5EDF8>
31 <main.MyClassObject object at 0x01D8B550>
32 <function MyClassObject.get..class_method at 0x01D5EDF8>
33 <class ‘main.C’>
34 <class ‘main.C’>
35

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

01D69108>
10 <staticmethod object at 0x01D8B4F0>
11 <function C.test_static_method at 0x01D69108>
12 静态方法测试
13 静态方法测试
14
15 自定义静态方法测试
16 <function C.test_my_static_method at 0x01D69078>
17 <main.MyStaticObject object at 0x01D8B510>
18 <function C.test_my_static_method at 0x01D69078>
19 自定义静态方法测试
20 自定义静态方法测试
21
22 类方法测试
23 <bound method type.test_class_method of <class ‘main.C’>>
24 <classmethod object at 0x01D8B530>
25 <bound method type.test_class_method of <class ‘main.C’>>
26 <class ‘main.C’>
27 <class ‘main.C’>
28
29 自定义类方法测试
30 <function MyClassObject.get..class_method at 0x01D5EDF8>
31 <main.MyClassObject object at 0x01D8B550>
32 <function MyClassObject.get..class_method at 0x01D5EDF8>
33 <class ‘main.C’>
34 <class ‘main.C’>
35

[外链图片转存中…(img-PuguhyDT-1719254052576)]
[外链图片转存中…(img-GGUsHw5e-1719254052577)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值