发布于2019-08-05 19:33 阅读(1017) 评论(0) 点赞(3) 收藏(4)
话说三国时期曹军于官渡大败袁绍,酒席之间,曹操诗兴大发,吟道:喝酒唱歌,人生真爽! 众将直呼:"丞相好诗",于是命印刷工匠刻板印刷以流传天下; 待工匠刻板完成,交与曹操一看,曹操感觉不妥,说道:"喝酒唱歌,此话太俗,应改为'对酒当歌'较好",于是名工匠重新刻板,当时还没有出现活字印刷术,如果样板要改,只能重新刻板,工匠眼看连夜刻版之工,彻底白费,心中叫苦不迭。可也只得照办。 版样再次出来请曹操过目,曹操细细一品,觉得还是不好,说”人生真爽太过直接,应该改问语才够意境,因此应改为‘对酒当歌,人生几何?’“,于是.... 在活字印刷术还没出现之前,如果版样有改动,只能重新雕刻。而且在印刷完成后,这个样板就失去了它的价值,如果需要其他样板只能重新雕刻。而活字印刷术的出现就大大改善了印刷技术。如上例”喝酒唱歌,人生真爽“,如果用活字印刷,只需要改四个字就可,其余工作都未白做。岂不快哉!! 活字印刷也反应了OOP。当要改动时,只需要修改部分,此为 可维护;当这些字用完后,并非就完全没有价值了,它完全可以在后来的印刷中重复使用,此乃 可复用;此诗若要加字,只需另刻字加入即可,这就是 可扩展;字的排列可以横排,也可以竖排,此是 灵活性好。
# 上述案列反应了面向对象的优点,即可维护性高,扩展性强,复用性高! # 这些特点非常适用于用户需求变化频繁的互联网应用程序,这是学习面向对象的重要原因 # 但是面向对象设计的程序需涉及类与对象,相应的复杂度会提高! # # 并非所有程序都需要较高的扩展性,例如系统内核,一旦编写完成,基本不会再修改,使用面向过程来设计则更适用
面向对象: # 是一种编程思想,是前辈们总结的编程经验,指导程序员如何编写出更好的程序
核心: # 对象
程序就是一系列对象的集合,程序员负责调度控制这些对象来交互着完成任务 在面向对象中程序员的角度发生了改变,从具体的操作者变成了指挥者。
强调:对象不是凭空产生的,需要我们自己设计
''' 优点: 1.可扩展性高 2.灵活性高 3.重用性高 缺点: 1.程序的复杂度提高了 2.无法准确预知结果 '''
使用场景: # 对扩展性要求较高的程序,通常是直接面向用户的,例如qq 微信
注意点: # 不是所有的程序都要采用面向对象,要根据实际需求来选择
面向对象的两大核心: # 类与对象
''' 类即类型、类别,是一种 抽象概念 是一系列具备相同特征和相同行为的对象的集合 '''
''' 对象就是具体存在的某个事物,具备自己的特征和行为 对象就是特征和技能的结合体 '''
''' 类包含一系列对象 对象属于某个类 在现实中先有对象再有类,程序中先有类再有对象 我们必须先告诉计算机这类的对象有什么特征有什么行为 '''
结论: # 在面向对象编程时,第一步需要考虑需要什么样的对象,对象具备什么样的特征和行为,从而根据这些信息总结出需要的类
class 类的名称: # 类中的内容,描述属性和技能 # 描述属性用变量 # 描述行为用函数 ''' 类名书写规范: 1.见名知意 2.名称是大驼峰式(驼峰就是单词首字母大写,大驼峰就是第一个字母大写,小驼峰是第一个字母小写) 3.其他规范与变量大致相同 '''
''' 属性可以写在类中 类中的属性,是对象公共的 也可以写在对象中 对象中的属性,每个对象独特的(不一样的) 如果类和对象中存在同样的属性,先访问对象,如果没有再访问类 '''
''' 增加属性 对象变量名称.属性名称 = 属性值 egon.male = 'male' 删除属性 del 对象的变量名称.属性名称 del egon.male 修改属性 对象.属性 = 新的值 查看所有属性,访问的是对象的所有属性 对象.__dict__ --> dict 可以访问调用者自身的名称空间 访问他的类 对象.__class__ 返回类 '''
class Student: ''' 这是Student类的注释 ''' def __init__(self, name): self.name = name class TeachOfOldBoy: company = 'oldboy' def __init__(self, name): self.name = name # ---------- 对象新增、修改、查看、删除属性 ------------- xuzhaolong = Student('xzl') print(xuzhaolong.name) # 对象.属性 --> 访问对象的属性 # xzl # print(xuzhaolong.age) # 访问不存在的属性会报错'Student' object has no attribute 'age' xuzhaolong.age = 18 # 对象.属性 = 值 --> 为对象添加新属性 print(xuzhaolong.age) # 18 xuzhaolong.age = 28 # 对象.属性 = 新值 --> 修改属性的值(如果该对象已有此属性) print(xuzhaolong.age) # 28 del xuzhaolong.age # 删除对象的属性 # print(xuzhaolong.age) # 会报错,属性已被删除,类中(属性的查找顺序:对象-->父类-->...如果还有父类,其他父类...-->Object)没有这个属性,AttributeError: 'Student' object has no attribute 'age' print(TeachOfOldBoy.__dict__) # __dict__查看调用者的名称空间里的名字 # {'__module__': '__main__', 'company': 'oldboy', '__init__': <function TeachOfOldBoy.__init__ at 0x0000026D1AC8A9D8>, '__dict__': <attribute '__dict__' of 'TeachOfOldBoy' objects>, '__weakref__': <attribute '__weakref__' of 'TeachOfOldBoy' objects>, '__doc__': None} print(xuzhaolong.__dict__) # {'name': 'xzl', 'age': 28} # ---------- __class__ 查看调用者所属类型(python里类也是一种数据类型) ------------- print(TeachOfOldBoy.__class__) # __class__ 查看调用者所属类 # <class 'type'> print(xuzhaolong.__class__) # <class '__main__.Student'> # ---------- __doc__ 查看调用者的注释 ------------- print(TeachOfOldBoy.__doc__) # __doc__ 查看调用者的注释 # None print(Student.__doc__) # __doc__ 查看调用者所属类的注释 # # 这是Student类的注释 # print(xuzhaolong.__doc__) # __doc__ 查看调用者所属类的注释 # # 这是Student类的注释 # # ------------ 类中的属性与对象 ----------------- egon = TeachOfOldBoy('egon') print(egon.company) # oldboy egon.company = 'OldBoy' print(egon.company) # 修改对象的继承的属性不影响类中的属性 # OldBoy print(TeachOfOldBoy.company) # oldboy
属性的查找顺序: # 属性的查找顺序:先找自己的,再找类的,再父类。。。。一直往上找到object,再没有就报错
''' __init__方法 特点 1.当实例化对象时,会自动执行__init__方法 2.会自动将对象作为第一个参数传入,对象参数名称为self,self这个名字可以改,但不建议(一眼就知道是对象本身了) 功能 用户给对象赋初始值 ''' # 初始化,不仅仅只是赋初值,还可以做一些其他操作,来保证对象的正常生成
''' 之前十个老师,每个老师都要输姓名年龄等,而属性的值又不一样,就不能直接定义成类的属性 每定义一个对象都要写一次,很麻烦 那么我们可以使用函数来简化这个赋值操作 class Cls: # 定义一个类 pass def init(obj, kind, color, age): # 定义一个方法来简化给对象添加(定制)属性 obj.kind = kind # 即 对象.属性 = 值(变量的) --> 像什么? 给对象添加属性嘛 obj.color = color obj.age = age obj1 = Cls() # 实例化出一个对象 init(obj1, "泰日天", '棕色', 2) # 通过调用 init 函数来给该对象添加属性 obj2 = Cls() init(obj2, "拆家犬", '黑白', 1) # 这样子就有了两个对象,且都已经有了各自的属性了 ''' class Dog: def __init__(self, kind, color, age): # print(locals()) # {'age': 2, 'color': '棕色', 'kind': '泰日天', 'self': <__main__.Dog object at 0x000002985BE586D8>} self.kind = kind self.color = color self.age = age # __init__ 函数不允许写返回值(不能写,只能返回None,写return None 没有意思) 规定如此 ''' 不过在类里面直接写这个 init 函数会更方便(python内部做了一些处理) 如上,当实例化对象时,会自动执行这个 __init__ 方法 会自动将调用这个类实例化的对象作为第一个参数传入,对象参数名称为self ''' # 那么在实例化的时候就可以简写成这样了,四行变两行 teidi = Dog("泰日天", '棕色', 2) # print(teidi.__dict__) # {'kind': '泰日天', 'color': '棕色', 'age': 2} erha = Dog("拆家犬", '黑白', 1) ''' 其实上面的写法还可以有优化,那个__init__ 函数还可以写得更简洁一点(参数越多越明显) def __init__(self, kind, color, age): lcs = locals() lcs.pop('self') self.__dict__.update(lcs) 上面写法中的locals()内置函数在 __init__ 函数中,可以获取 __init__ 函数名称空间里的那些名字,它是一个字典 # print(locals()) # {'age': 2, 'color': '棕色', 'kind': '泰日天', 'self': <__main__.Dog object at 0x000002985BE586D8>} 我们将其赋给一个中间字典接收,将多余的 self 键值对去掉,就是我们对象想要的属性 而对象.__dict__正好也是一个字典 # print(teidi.__dict__) # {'kind': '泰日天', 'color': '棕色', 'age': 2} 都是字典?字典的update()方法还记得吗? 将这个中间字典update()到对象的.__dict__ 中,即完成了对象的属性添加 self.__dict__.update(lcs) '''
备注:关于python内一些 __名字__ 这种属性是什么情况,可以参考这篇博客哦(都说不重要,但总有我这样的好奇宝宝嘛)~ Python常用内建方法:__init__,__new__,__class__的使用详解
对象的精髓所在就是将数据和处理数据的函数整合到一起了,这样一来,拿到一个对象就同时拿到了需要处理的数据以及处理数据的函数
''' ******* 这一块基础概念是重点 ******* 对象绑定方法:self --> 默认传入对象 默认情况下,类中的方法都是对象绑定方法 当使用对象调用时 其特殊之处在于调用该函数时会自动传入对象本身作为第一个参数 当使用类名来调用时就是一个普通函数,有几个参数就传几个参数 类绑定方法:@classmethod cls(加上@classmethod装饰后自己将self改为cls(class是关键字)) --> 默认传入类 给类的抽象方法,默认传入类作为参数 特殊之处:不管用类还是对象调用,都会自动传入类本身,作为第一个参数 何时绑定给对象:当函数逻辑需要访问对象中的数据时 何时绑定给类:当函数逻辑需要访问类中的数据时 非绑定方法:@staticmethod 装饰成普通函数,不管谁调都一样 既不需要访问类的数据也不需要访问对象的数据 定义时有几个参数调用时就需要传入几个参数 ''' class Dog: species = 'dog' # 初始化方法 __init__ 也属于对象绑定方法 def __init__(self, kind, nickname, skill): self.kind = kind self.nickname = nickname self.skill = skill # 这就属于一个对象绑定方法,默认将对象作为第一个参数传入(调用的时候不需要手动传入) def introduce(self): print(f"我是{self.kind},我能{self.skill},人送外号{self.nickname}") # 类绑定方法 @classmethod def tell_species(cls): # 先写装饰器再写函数,默认参数就是cls了,写完函数再装饰的话,记得把self换成cls,表示参数是一个类 print(f"我的物种是{cls.species}") # 非绑定方法(既不需要传入类,也不需要传入对象) @staticmethod def normal_func(arg1, arg2): print(f"参数一:{arg1} 参数二:{arg2},这只是一个普通方法啦~") taidi = Dog('泰迪', '泰日天', '日天') erha = Dog('二哈', '拆家犬', '拆家') # --------绑定对象方法的调用 taidi.introduce() erha.introduce() # 我是泰迪,我能日天,人送外号泰日天 # 我是二哈,我能拆家,人送外号拆家犬 Dog.introduce(erha) # 类调用对象的方法要手动把对象传入进去 # 我是二哈,我能拆家,人送外号拆家犬 # --------类绑定方法调用 Dog.tell_species() taidi.tell_species() # 可以直接调用,无需手动传入 class # 我的物种是dog # 我的物种是dog # --------非绑定方法调用 Dog.normal_func(1, 2) # 非绑定方法,定义时有几个参数,调用时就要传几个参数 taidi.normal_func(1, 2) # 非绑定方法,定义时有几个参数,调用时就要传几个参数 # 参数一:1 参数二:2,这只是一个普通方法啦~ # 参数一:1 参数二:2,这只是一个普通方法啦~
如单机游戏的存档(把对象的数据等信息存储到文件中,下次启动再读取回来) --> 游戏扩展
import pickle class Student: def __init__(self, name): self.name = name def say_hi(self): print("name:", self.name) def save(self): with open(self.name, "wb") as f: # pickle 模块操作文件必须是b 模式 pickle.dump(self, f) # 利用pickle 模块,将传入的对象序列化到了文件中(json模块不支持对象这种类型) @staticmethod def get(name): with open(name, "rb") as f: obj = pickle.load(f) # 利用pickle 模块,将文件中的对象反序列化成python中的对象 return obj # 将rose 和 jack两个从内存中对象序列化到文件中 stu = Student("rose") stu.save() stu2 = Student("jack") stu2.save() # 将他两反序列化出来到内存中 obj = Student.get("rose") # 调用类中的方法(类绑定方法)从文件中将对象加载到内存中 print(obj.name) # 使用该对象获取属性值 # rose obj2 = Student.get("jack") print(obj2.name) # jack print(Student.__name__) # 获取类名 # Student # 反序列化出来的对象和序列化的那个对象已经不是同一个对象了 print(id(stu), id(obj)) # 2161209937816 2161209971880 print(stu.name, obj.name) # rose rose print(id(stu2), id(obj2)) # 2161209937872 2161209971824 print(stu2.name, obj2.name) # jack jack obj2.name = 'jack2' print(stu2.name, obj2.name) # jack jack2
import random import time class Hero: def __init__(self, name, health, attack, q_hurt, w_hurt, e_hurt): lcs = locals() lcs.pop('self') self.__dict__.update(lcs) def attack(self, enemy): print(f"-- {self.name} --使用普通攻击攻击了-- {enemy.name} --,造成了 {self.attack} 点伤害,{enemy.name} 剩余 {enemy.health} 点生命值。\033[0m") enemy.health -= self.attack def Q(self, enemy): print(f"\033[0m-- {self.name} --使用Q技能攻击了-- {enemy.name} --,造成了 {self.q_hurt} 点伤害,{enemy.name} 剩余 {enemy.health} 点生命值。\033[0m") enemy.health -= self.q_hurt def W(self, enemy): print(f"\033[32m-- {self.name} --使用W技能攻击了-- {enemy.name} --,造成了 {self.w_hurt} 点伤害,{enemy.name} 剩余 {enemy.health} 点生命值。\033[0m") enemy.health -= self.w_hurt def E(self, enemy): print(f"\033[35m-- {self.name} --使用E技能攻击了-- {enemy.name} --,造成了 {self.e_hurt} 点伤害,{enemy.name} 剩余 {enemy.health} 点生命值。\033[0m") enemy.health -= self.e_hurt def check_hero(enemy, team): if enemy.health <= 0: print(f"\033[31m** {enemy.name} ** 阵亡。\033[0m") if team == 'blue': blue_team.remove(enemy) elif team == 'red': red_team.remove(enemy) def get_random_skill(): return skill_list.get(random.randint(1, 4)) def get_random_blue_hero(): return blue_team[random.randint(0, len(blue_team) - 1)] def get_random_red_hero(): return red_team[random.randint(0, len(red_team) - 1)] blue_team = [ Hero('瑞文', 465, 65, 30, 25, 70), Hero('提莫', 300, 35, 50, 40, 60), ] red_team = [ Hero('李白', 320, 60, 35, 29, 77), Hero('鲁班', 280, 79, 35, 40, 80), ] skill_list = { 1: Hero.attack, 2: Hero.Q, 3: Hero.W, 4: Hero.E, } while len(red_team) > 0 and len(blue_team) > 0: skill = get_random_skill() blue = get_random_blue_hero() red = get_random_red_hero() flag = random.randint(0, 1) if flag: skill(blue, red) check_hero(red, 'red') else: skill(red, blue) check_hero(blue, 'blue') time.sleep(0.3) if len(red_team) == 0: print(f"蓝色方获胜!") print(f"蓝色方所剩英雄状态为:") for hero in blue_team: print(f"{hero.name} 剩余生命值 {hero.health}") elif len(blue_team) == 0: print(f"红色方获胜!") print(f"红色方所剩英雄状态为:") for hero in red_team: print(f"{hero.name} 剩余生命值 {hero.health}")
注释版
import random import time # 定义一个英雄类,表示英雄这一类的共同特征 class Hero: def __init__(self, name, health, attack, q_hurt, w_hurt, e_hurt): lcs = locals() lcs.pop('self') self.__dict__.update(lcs) ''' ********************************** 上述代码讲解 ************************************* # 每次调用类生成对象的时候都会执行这里面的代码,并将对象作为第一个参数self 传进来 print(locals()) # {'e_hurt': 70, 'w_hurt': 25, 'q_hurt': 30, 'attack': 65, 'health': 465, 'name': '瑞文', 'self': <__main__.Hero object at 0x000002371823B278>} lcs = locals() # 这个locals()在 __init__ 函数里 可以获取 __init__ 函数名称空间里的那些名字,他是一个字典 lcs.pop('self') # 发现上面的 locals() 多了一个 self 是不需要的,那就把它删掉 print(lcs) # {'e_hurt': 70, 'w_hurt': 25, 'q_hurt': 30, 'attack': 65, 'health': 465, 'name': '瑞文'} # 这些内容正是初始化对象时想做的事(只不过是 对象.e_hurt = 70 这样的形式而已) self.__dict__.update(lcs) # 将这些东西放到对象里,就重复了n变 self.参数 = 参数 (self.name = name)这样的动作 print(self.__dict__) # {'e_hurt': 70, 'w_hurt': 25, 'q_hurt': 30, 'attack': 65, 'health': 465, 'name': '瑞文'} 最初始的写法: self.name = name self.health = health self.attack = attack self.q_hurt = q_hurt self.w_hurt = w_hurt self.e_hurt = e_hurt ''' def attack(self, enemy): enemy.health -= self.attack print(f"-- {self.name} --使用普通攻击攻击了-- {enemy.name} --,造成了 {self.attack} 点伤害,{enemy.name} 剩余 {enemy.health} 点生命值。\033[0m") def Q(self, enemy): enemy.health -= self.q_hurt print(f"\033[0m-- {self.name} --使用Q技能攻击了-- {enemy.name} --,造成了 {self.q_hurt} 点伤害,{enemy.name} 剩余 {enemy.health} 点生命值。\033[0m") def W(self, enemy): enemy.health -= self.w_hurt print(f"\033[32m-- {self.name} --使用W技能攻击了-- {enemy.name} --,造成了 {self.w_hurt} 点伤害,{enemy.name} 剩余 {enemy.health} 点生命值。\033[0m") def E(self, enemy): enemy.health -= self.e_hurt print(f"\033[35m-- {self.name} --使用E技能攻击了-- {enemy.name} --,造成了 {self.e_hurt} 点伤害,{enemy.name} 剩余 {enemy.health} 点生命值。\033[0m") def check_hero(enemy, team): if enemy.health <= 0: # \033[31m 这种格式的是打印时的颜色控制(颜色可参考 https://www.cnblogs.com/easypython/p/9084426.html) print(f"\033[31m** {enemy.name} ** 阵亡。\033[0m") if team == 'blue': blue_team.remove(enemy) elif team == 'red': red_team.remove(enemy) # 随机选择一种攻击方式 def get_random_skill(): # random_index = random.randint(1, 4) # random_skill = skill_list.get(random_index) # return random_skill # 函数名当做返回值返回,拿到可以直接加括号调用执行函数 return skill_list.get(random.randint(1, 4)) # 上面代码的简便写法 # 随机选择一个蓝色方英雄 def get_random_blue_hero(): # 返回 blue_team 这个列表的索引为 random.randint(0, len(blue_team) - 1) 返回值的元素(英雄对象) # return blue_team[random.randint(0, len(blue_team) - 1)] # 下面几行的简便写法 random_idndex = random.randint(0, len(blue_team) - 1) hero = blue_team[random_idndex] return hero # 随机选择一个红色方英雄 def get_random_red_hero(): return red_team[random.randint(0, len(red_team) - 1)] # 蓝色方英雄阵容 --- 可自定义 --- # 方便随机数取英雄对象 blue_team = [ # 英雄名 生命值 普通攻击力 Q技能伤害 W技能伤害 E技能伤害 # 瑞文 465 65 30 25 70 Hero('瑞文', 465, 65, 30, 25, 70), Hero('提莫', 300, 35, 50, 40, 60), Hero('锤石', 600, 15, 20, 0, 32), ] # 红色方英雄阵容 --- 可自定义 --- # 方便随机数取英雄对象 red_team = [ Hero('李白', 320, 60, 35, 29, 77), Hero('鲁班', 280, 79, 35, 40, 80), Hero('盾山', 800, 3, 3, 3, 3), ] # 技能数字对应表(方便根据随机数取技能) skill_list = { 1: Hero.attack, 2: Hero.Q, 3: Hero.W, 4: Hero.E, } def run(): while len(red_team) > 0 and len(blue_team) > 0: # 调用方法随机获得一个技能 skill = get_random_skill() # 调用方法随机获得一个蓝色方英雄 blue = get_random_blue_hero() # 调用方法随机获得一个红色方英雄 red = get_random_red_hero() # 随机选择一方为攻击方(那么另一方就是被攻击方) flag = random.randint(0, 1) if flag: skill(blue, red) check_hero(red, 'red') else: skill(red, blue) check_hero(blue, 'blue') # 暂停0.3秒,可以慢慢看战斗过程 time.sleep(0.3) # 如果有任意一方没有英雄了,即游戏结束 if len(red_team) == 0: print(f"蓝色方获胜!") print(f"蓝色方所剩英雄状态为:") for hero in blue_team: print(f"{hero.name} 剩余生命值 {hero.health}") elif len(blue_team) == 0: print(f"红色方获胜!") print(f"红色方所剩英雄状态为:") for hero in red_team: print(f"{hero.name} 剩余生命值 {hero.health}") if __name__ == '__main__': run() ''' 战斗记录 ************************** 省略n多中间战斗步骤 ********************************* -- 锤石 --使用W技能攻击了-- 盾山 --,造成了 0 点伤害,盾山 剩余 42 点生命值。 -- 盾山 --使用E技能攻击了-- 瑞文 --,造成了 3 点伤害,瑞文 剩余 289 点生命值。 -- 瑞文 --使用E技能攻击了-- 盾山 --,造成了 70 点伤害,盾山 剩余 -28 点生命值。 ** 盾山 ** 阵亡。 蓝色方获胜! 蓝色方所剩英雄状态为: 瑞文 剩余生命值 289 锤石 剩余生命值 235 战斗记录2 ************************** 省略n多中间战斗步骤 ********************************* -- 盾山 --使用普通攻击攻击了-- 锤石 --,造成了 3 点伤害,锤石 剩余 11 点生命值。 -- 锤石 --使用普通攻击攻击了-- 盾山 --,造成了 15 点伤害,盾山 剩余 288 点生命值。 -- 盾山 --使用E技能攻击了-- 瑞文 --,造成了 3 点伤害,瑞文 剩余 -1 点生命值。 ** 瑞文 ** 阵亡。 -- 盾山 --使用普通攻击攻击了-- 锤石 --,造成了 3 点伤害,锤石 剩余 8 点生命值。 -- 盾山 --使用普通攻击攻击了-- 锤石 --,造成了 3 点伤害,锤石 剩余 5 点生命值。 -- 盾山 --使用W技能攻击了-- 锤石 --,造成了 3 点伤害,锤石 剩余 2 点生命值。 -- 盾山 --使用Q技能攻击了-- 锤石 --,造成了 3 点伤害,锤石 剩余 -1 点生命值。 ** 锤石 ** 阵亡。 红色方获胜! 红色方所剩英雄状态为: 盾山 剩余生命值 288 ''' ''' 有红蓝两方英雄(可自定义个数) 随机一方英雄使用随机攻击方式攻击另一方英雄,任意一方英雄全部阵亡则游戏结束 每个英雄有 名字、生命值、普通攻击、Q技能攻击、W技能攻击、E技能攻击以及对应的伤害值 当生命值为 0 时阵亡,不再参与战斗 '''
调用类生成对象发生的一些事情(对比变量、模块名称空间生成等)
属性的查找顺序(画图表示吧)
先找自己的,再找父类的,一级一级往上找,直到基类object,再没有报错
英雄大乱斗案例
序列化、反序列化对象(保存、读取对象)(游戏退出,读档)
作者:lg
链接:https://www.pythonheidong.com/blog/article/7095/9c725b68e7f9b7e431e2/
来源:python黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 python黑洞网 All Rights Reserved 版权所有,并保留所有权利。 京ICP备18063182号-1
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!