hello, 小伙伴们,好久不见了, 沉默一段时间得我又回来了, 这一次带来的是一些自己原来总结的小案例, 希望可以帮助到你或者能给你带来启发喔~
首先来一些比较基础的案例:
1.列表的操作:
按照索引删除列表中的某些元素
lst = ["礼李白", "关汉卿", "曹雪芹", "杜甫", "李贺"] del lst[1:3] print(lst) # ["李白", "杜甫", "李贺"]
2.字典的基本操作:
setdefault, 字典添加键值对的操作,没有添加进去, 有的话不改变, 没有的话, 添加
dic = {} dic['name'] = '周润发' dic['age'] = 18 print(dic) # {'name': '周润发', 'age': 18} dic.setdefault("李嘉诚", "房地产") dic.setdefault("李嘉诚", "房地产1") print(dic) # {'name': '周润发', 'age': 18, '李嘉诚': '房地产'}
update,把字典的内容更新到字典1里面去, key重名的话, 修改替换, 不重名, 添加
dic = {"id": 123, "name": 'sylar', "age": 18} dic1 = {"id": 456, "name": "麻花藤", "ok": "wtf"} dic.update(dic1) print(dic) # {'id': 456, 'name': '麻花藤', 'age': 18, 'ok': 'wtf'}
get,查询字典中是否存在该值,存在返回value, 不存在,返回默认值
dict = {'id': 456, 'name': '麻花藤', 'age': 18, 'ok': 'wtf'} print(dic.get("name")) # 麻花藤 print(dic.get("names")) # None print(dic.get("names", "牛B")) # 牛B
案例2: 由两个数据组返回新的数据统计
cars = ['鲁A32444', '鲁B12333', '京B8989M', '黑C49678', '黑C46555', '沪B25041', '黑C34567'] locations = {'沪': '上海', '京': '北京', '黑': '黑龙江', '鲁': '山东', '鄂': '湖北', '湘': '湖南'} result = {} # 统计车牌照并且在新的结果里显示各省的牌照数量 比如{"河北": 2}, 可以使用字典的get方法 for pai in cars: # 鲁A32444 result[locations[pai[0]]] = result.get(locations[pai[0]], 0) + 1 print(result) # {'山东': 2, '北京': 1, '黑龙江': 3, '上海': 1}
列表中的enumerate的另类用法:
goods = [{"name": "电脑", "price": 1999}, {"name": "鼠标", "price": 10}, {"name": "游艇", "price": 20}, {"name": "美女", "price": 998}, ] # 原数据如上面所示,现在的需求是按照 这样的方式进行显示 比如 1 电脑 1999 2 鼠标 10 for el, value in enumerate(goods): print(str(el + 1) + ' ' + value['name'] + ' ' + str(value['price'])) # 这样的结果就是 # 1 电脑 1999 # 2 鼠标 10 # 3 游艇 20 # 4 美女 998
案例四: 判断百家姓
首先需要准备的是百家姓
first_names = """ 赵钱孙李,周吴郑王。 冯陈褚卫,蒋沈韩杨。 朱秦尤许,何吕施张。 孔曹严华,金魏陶姜。 戚谢邹喻,柏水窦章。 云苏潘葛,奚范彭郎。 昌韦昌马,苗凤花方。 俞任袁柳,酆鲍史唐。 费廉岑薛,雷贺倪汤。 滕殷罗毕,郝邬安常。 乐于时傅,皮卞齐康。 伍余元卜,顾孟平黄。 和穆萧尹,姚邵湛汪。 祁毛禹狄,米贝明臧。 计伏成戴,谈宋茅庞。 熊纪舒屈,项祝董梁。 杜阮蓝闵,席季麻强。 贾路娄危,江童颜郭。 梅盛林刁,钟徐邱骆。 高夏蔡田,樊胡凌霍。 虞万支柯,昝管卢莫。 经房裘缪,干解应宗。 丁宣贲邓,郁单杭洪 包诸左石,崔吉钮龚。 程嵇邢滑,裴陆荣翁。 荀羊於惠,甄曲家封。 芮羿储靳,汲邴糜松。 井段富巫,乌焦巴弓。 牧隗山谷,车侯宓蓬。 全郗班仰,秋仲伊宫。 宁仇栾暴,甘钭厉戎。 祖武符刘,景詹束龙。 叶幸司韶,郜黎蓟薄。 印宿白怀,蒲邰从鄂。 索咸籍赖,卓蔺屠蒙。 池乔阴鬱,胥能苍双。 闻莘党翟,谭贡劳逄。 姬申扶堵,冉宰郦雍。 卻璩桑桂,濮牛寿通。 边扈燕冀,郏浦尚农。 温别庄晏,柴瞿阎充。 慕连茹习,宦艾鱼容。 向古易慎,戈廖庾终。 暨居衡步,都耿满弘。 匡国文寇,广禄阙东。 欧殳沃利,蔚越夔隆。 师巩厍聂,晁勾敖融。 冷訾辛阚,那简饶空。 曾毋沙乜,养鞠须丰。 巢关蒯相,查后荆红。 游竺权逯,盖益桓公。 万俟司马,上官欧阳。 夏侯诸葛,闻人东方。 赫连皇甫,尉迟公羊。 澹台公冶,宗政濮阳。 淳于单于,太叔申屠。 公孙仲孙,轩辕令狐。 钟离宇文,长孙慕容。 鲜于闾丘,司徒司空。 丌官司寇,仉督子车。 颛孙端木,巫马公西。 漆雕乐正,壤驷公良。 拓跋夹谷,宰父谷梁。 晋楚闫法,汝鄢涂钦。 段干百里,东郭南门。 呼延归海,羊舌微生。 岳帅缑亢,况郈有琴。 梁丘左丘,东门西门。 商牟佘佴,伯赏南宫。 墨哈谯笪,年爱阳佟。 第五言福,百家姓终。 """ # 输入一个姓名, 判断是否在百家姓中。 # 对于单个姓, 直接判断是不是in就行, 但是有复姓, 这就需要稍微做一下处理 name = input('请输入您的姓名:').strip() s ='' for c in name: s = s + c print(s) if s in first_names: print('在百家姓里') break else: print('不在百家姓里') # 这个方法可以判断复姓, 但是要是输入的复姓不在刚开始的就判断不出来了, 比如上慕容家,这样就判断不到了,但是一般也不会这样输入, 其实也可以处理, 比如设定最大是两个字符, 可以在拼接下一个时,如果长度大于3就把第一个字符剔除掉, 也可以判断 # 代码如下 name = input('请输入您的姓名:').strip() s ='' for c in name: s = s + c if len(s) >= 3: s1 = s[1::] if s1 in first_names: print(s1) print('在百家姓里') break else: print('不在百家姓里') else: if s in first_names: print(s) print('在百家姓里') break else: print(s) print('不在百家姓里') # 当然还可以做优化,这里不再做更深层次的优化
字符的编码和解码
s = "我是文字" bs = s.encode("GBK") # 我们这样可以获取到GBK的文字 # 把GBK转换成UTF-8 # 首先要把GBK转换成unicode. 也就是需要解码 s = bs.decode("GBK") # 解码 # 然后需要进行重新编码成UTF-8 bss = s.encode("UTF-8") # 重新编码 print(bss) # 我是文字
写一个登录注册功能, 涉及文件操作(附带只有三次登录机会 )
def regist(username, password): # wusir # 1. 检查用户名是否重复 f = open("user_info", mode="r+", encoding="utf-8") for line in f: if line == "": # 防止空行影响程序运行 continue user_info_username = line.split("_")[0] # 这个边缘问题记得要记得排除 !!!!! if username == user_info_username: # 用户名重复了 return False else: # 2. 写入到文件中 f.write(username+"_"+password+" ") f.flush() f.close() return True def login(username, password): f = open("user_info", mode="r", encoding="UTF-8") for line in f: if line.strip() == username+"_"+password: f.close() return True else: f.close() return False for i in range(2, -1, -1): ret = login(input("请输入用户名:"), input("请输入密码:")) if ret: print("恭喜你. 登录成功") break else: print("用户名或密码错误, 还有%s次机会" % i)
参数的聚合:
def func(*num): print(num, type(num)) # (1, 2, 3, 11, 22, 33, 111, 222, 333) <class 'tuple'> func(*(1, 2, 3), *[11, 22, 33], *(111, 222, 333)) def func(**shenfen): print(shenfen) # {'张无忌': '明教教主', '谢逊': '金毛狮王', '范瑶': '光明右使'} func(**{'张无忌': '明教教主'}, **{'谢逊': '金毛狮王'}, **{'范瑶': '光明右使'})
参数的打散:
def func(*args): print(*args) # 大白菜 小白菜 娃娃菜 包头菜, 就是四个参数,将其打散成四个参数。 print(args) # '大白菜', '小白菜', '娃娃菜', '包头菜') lst = ['大白菜', '小白菜', '娃娃菜', '包头菜'] func(*lst) # 在实参位置打散,
私有的理解,私有的意思就是,就是自己的, 别人不能看也不能调用, 只能自己内部调用,
class Person: def __init__(self, laopo, mimi): self.__laopo = laopo # 私有的 self.__mimi = mimi panda = Person("banana", "panda爱吃banana") print(panda.__mimi) # 这样访问会报错, # 不报错的方法, 自己的内部成员访问 class Person: def __init__(self, laopo, mimi): self.__laopo = laopo # 私有的 self.__mimi = mimi def tell(self): print("世界广播") return self.__mimi panda = Person("banana", "panda爱吃banana") mimi = panda.tell() # 通过一个公有方法,访问到了它的私密美容 print(panda.__mimi) # panda爱吃banana # 私有的内容不能直接访问. 但是如果对方开辟了外界访问的通道(公共方法). 那可以通过这个公共的方法来获取到私有的内容. 这样做的好处是. 外界, 只能看, 但是改不了.不单单实例变量有私有的. 类变量(静态变量)一样拥有这样的属性 # __yue是一个私有的方法. 只能在类中自己调⽤用. 类外面不能访问.job是一个成员方法. 并且是一个开放的方法. 在类外界可以被访问到 同样的. 类中的私有方法也是相对而言的. 我们可以通过其他方法来访问到这样的方法. class Person: def __init__(self): pass def __yue(self): print("我要约会") def job(self): print("我要工作") self.__yue() # 在自己类中访问自己的其他方法. 哪怕是私有的. 也是自己在⽤用 p = Person() p.job()
类变量是给类用, 多个对象之间可以进行共享, 最好是用类名来进行访问, 这样更加规范
类的成员- 方法:成员方法(实例方法)、静态方法、类方法
静态方法和类方法在python2.2中被引用,经典类和新式类都可以使用,同时,一对内建函数staticmethod和classmethod被引入, 用来转化类中方法为这两种方法之一。
静态方法: 是类中的函数, 不需要实例,主要用来存放逻辑性代码, 不会涉及到类中方法和属性的操作, 可以理解为将静态方法存在此类的名称空间中。
1 # 例子 2 # 想定义一个关于时间操作的类,其中有一个是获取当前时间的函数 3 import time 4 class TestTime(object): 5 def __init__(self, hour, minute, second): 6 self.hour = hour 7 self.minute = minute 8 self.second = second 9 10 @staticmethod 11 def showtime(): 12 return time.strftime("%H:%M:%S", time.localtime()) 13 14 15 print(TestTime.showtime()) 16 t = TestTime(2, 28, 10) 17 now_time = t.showtime() 18 print(now_time)
如上面的代码所示,使用静态函数,可以将获得时间的函数功能与实例解绑, 比如我想获取当前时间的字符串时,并不一定需要实例化对象, 更像一种命名空间。当然也可以在外面定义一个简单的方法来做这些, 但这样就扩散了类代码的关系到类定义的外面, 会导致以后的代码维护困难,静态函数可以通过类名以及实例两种方法调用。
类方法:
类方法是将类本身作为对象进行操作的方法, 和静态方法的区别在于:不管这个方式是从实例调用还是从类中调用, 他都用第一个参数被类传递过来。
应用:
# 做一个颜色的动态匹配 class ColorMatch: color = "color" @classmethod def result(cls): return cls.color class Black(ColorMatch): color = "black" class Gray(ColorMatch): color = "gray" g = Gray() print(g.color) # gray print(Gray.color) # gray
基类有一个抽象共性, 对于实际的颜色需要结合实际的类进行匹配
假设有一个学生类和一个班级类,想要实现的功能就是:
班级含有类方法:执行班级人数增加的操作、获取班级总人数 学生继承自班级类,实例化一个学生,班级人数都能增加。最后,想定义一些学生,然后获的班级的总人数。
1 # 这个问题用类方法做比较合适,因为实例化的是学生, 但是从学生这个案例中获得班级总人数是不合理的,同时,如果此昂要获取班级的总人数,生成一个班级的实例也是没必要的 2 class Class(object): 3 __num = 0 4 5 @classmethod 6 def add_student(cls): 7 cls.__num += 1 8 9 @classmethod 10 def get_student(cls): 11 return cls.__num 12 13 def __new__(cls, *args, **kwargs): 14 Class.add_student() 15 return super(Class, cls).__new__(cls) 16 17 18 class Student(Class): 19 def __init__(self, name): 20 self.name = name 21 22 23 a = Student("如花") 24 b = Student("思雨") 25 26 ret = Class.get_student() 27 print(ret) # 2
这里使用到了__new__,主要是为了在创建实例的时候调用人数增加的函数。
创建对象的真正步骤:
首先,在执行类名()的时候, 系统会自动先执行__new__()来开辟内存,此时新开出来的内存区域是空的,接着系统会调用__init__()来完成对象的初始化工作,按照时间轴来算,1.加载类 2.开辟内存(__new__) 3.初始化(__init__) 4.使用对象干xxxxx
反射的应用, 使用getattr反向去查找原文件中继承Base类的子类以及获取handler.py中所有成员名称和检查其他成员中是否是Base的子类,如果是的话则创建对象将其添加到obj列表中
首先是创建handler.py文件并添加进去类 class Base(object): pass class F1(Base): pass class F2(Base): pass class F3(F2): pass class F4(Base): pass class F5(object): pass class F6(F5): pass
接下来在run.py文件中写入相应的需求
1 # 首先还是先导入该文件 2 import handler 3 # 获取所有成员的名称 即 dir(handler) 4 print(dir(handler)) # ['Base', 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__'] 5 # 获取handler中叫Base的成员 6 print(getattr(handler,'Base')) # <class 'handler.Base'> 7 # 检查其他成员是否是Base类的子类(不包含Base),如果是则创建对象并添加到objs列表中 8 def func(): 9 name_lst = dir(handler) 10 new_lst = [] 11 # 去掉其中的双下划线方法 12 for el in name_lst: 13 if el.startswith('__') and el.endswith('__'): 14 new_lst.append(el) 15 # 列表不能边循环边删除所以得将要删除的放在一个新的列表中循环新列表删除就列表中的该元素。 16 for el in new_lst: 17 name_lst.remove(el) 18 base_sub_lst = [] 19 for name in name_lst: 20 cls = getattr(handler, name) 21 if issubclass(cls, getattr(handler, 'Base')) and cls != getattr(handler, 'Base'): 22 base_sub_lst.append(cls()) # 不加括号就是类, 加括号即创建新对象 23 print(base_sub_lst) # [<hadler.F1 object at 0x00000236153D6FD0>, <hadler.F2 object at 0x00000236153D6F98>, <hadler.F3 object at 0x00000236153DCC50>, <hadler.F4 object at 0x00000236153DCC88>] 24 25 26 func()
写一个类进行分页处理
1 class Pager(object): 2 3 def __init__(self, lst, pagesize): 4 self.lst = lst 5 self.pagesize = pagesize 6 7 def start(self): # 1 8 return self.__zhiding(1) 9 10 def end(self): # 最后一页 11 return self.__zhiding(self.totle) 12 13 def index(self): # 指定某一页 14 page = int(input("请输入你要显示的页码:")) 15 return self.__zhiding(page) 16 17 def __zhiding(self, page): 18 return self.lst[self.pagesize * (page - 1): self.pagesize * page] 19 20 @property 21 def totle(self): 22 if len(self.lst) % self.pagesize == 0: 23 total = len(self.lst) // self.pagesize 24 else: 25 total = len(self.lst) // self.pagesize + 1 26 return total 27 28 29 p = Pager([i for i in range(20000)], 100) 30 print(p.end()) 31 print(p.index())
获取obj中的所有字典类型的成员
1 class Foo: 2 def __init__(self): 3 self.name = '小猪' 4 self.age = 100 5 self.name = "alex" 6 7 @property 8 def haha(self): 9 return 10 10 11 12 obj = Foo() 13 setattr(obj, 'email', 'handsome@xx.com') 14 print(obj.__dict__) # 字典类型成员
使用traceback获取错误的堆栈信息,这个模块可以获取到我们每个方法的调用信息.又被称为堆栈信息, 对异常的处理, 这里是自定义异常。
1 # 自定义异常并且不使终端显示红色的报错信息, 使用tracback进行捕捉 2 import traceback 3 4 class GenderError(Exception): 5 pass 6 7 class Person: 8 def __init__(self, name, gender): 9 self.name = name 10 self.gender = gender 11 12 def nan_gu_ke_xi_zao(per): 13 if per.gender != "男": 14 raise GenderError("这里是男性洗澡堂,其他性别本禁止入内. ") 15 else: 16 pass 17 p1 = Person("李公公", "不详") 18 # nan_gu_ke_xi_zao(p1) 19 p2 = Person("安德鲁", "男") 20 try: 21 nan_gu_ke_xi_zao(p1) 22 val = traceback.format_exc() # 获取错误堆栈 23 print(val) 24 25 except GenderError as g: 26 print(g) # 这里打印的是抛出异常的内容 27 val = traceback.format_exc() # 获取错误堆栈 28 print(val) # 这里打印的是错误的堆栈信息
约束:约束指的就是对类的约束, Python中有两种方法解决这样的问题, 1.提取父类, 在父类中定义好方法, 这个方法中,什么都不干, 就抛异常就行, 子类集成这个父类, 必须重写这个方法, 不然访问的时候会报错, 2.使用元类来描述父类,元类给出一个抽象方法, 子类就必须给出抽象方法的具体实现, 也可以约束
1 class Base: 2 def login(self): 3 raise NotImplementedError("没有实现login方法") # 专业的写法 4 def kantie(self): 5 raise NotImplementedError("没有实现看帖功能") 6 # 张三 7 class Normal(Base): 8 def login(self): 9 print("普通人登陆") 10 11 # 李四 12 class Member(Base): 13 def denglu(self): 14 print("吧务登陆") 15 16 # 王五 17 class Admin(Base): 18 def login(self): 19 print("管理员登陆") 20 21 def login(obj): 22 print("产生验证码") 23 obj.login() # 标准在这里. 必须由login 24 print("进入主页") 25 26 # 场景 27 n = Normal() 28 m = Member() 29 a = Admin() 30 login(n) 31 login(m) # 这里会报错,即没有实现login的方法 32 login(a)
1 from abc import ABCMeta, abstractmethod 2 3 4 class Base(metaclass=ABCMeta): 5 @abstractmethod 6 def login(self): pass 7 8 9 # 张三 10 class Normal(Base): 11 def login(self): 12 print("普通人登陆") 13 14 15 # 李四 16 class Member(Base): 17 def login(self): 18 print("吧务登陆") 19 20 21 # 王五 22 class Admin(Base): 23 def denglu(self): 24 print("管理员登陆") 25 26 27 def login(obj): 28 print("产生验证码") 29 obj.login() # 标准在这里. 必须由login 30 print("进入主页") 31 32 33 # 场景 34 n = Normal() 35 m = Member() 36 a = Admin() 37 login(n) 38 login(m) 39 login(a) # a = Admin(); TypeError: Can't instantiate abstract class Admin with abstract methods login
日志的处理
1 import logging 2 3 logging.basicConfig(filename='app.log', 4 format='%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s', 5 datefmt='%Y-%m-%d %H:%M:%S', 6 level=40) # level 设置级别. 当你的信息的级别>=level的时候才会写入日志文件, 默认30 7 8 # CRITICAL = 50 9 # FATAL = CRITICAL 10 # ERROR = 40 11 # WARNING = 30 12 # WARN = WARNING 13 # INFO = 20 14 # DEBUG = 10 15 # NOTSET = 0 16 # 写日志 17 # logging.critical("我是critical") 18 # logging.error("我是error") 19 # logging.warning("我是警告") 20 # logging.info("我是基本信息") 21 # logging.debug("我是调试") 22 # logging.log(2, "我是自定义") 23 import traceback 24 25 for i in range(20): 26 try: 27 if i % 3 == 0: 28 raise FileNotFoundError("我是FileNotFountException") 29 elif i % 3 == 1: 30 raise StopIteration() 31 elif i % 3 == 2: 32 raise KeyError() 33 34 except FileNotFoundError as e: 35 val = traceback.format_exc() 36 logging.error(val) 37 except StopIteration as e: 38 val = traceback.format_exc() 39 logging.error(val) 40 except KeyError as e: 41 val = traceback.format_exc() 42 logging.error(val) 43 except Exception as e: 44 val = traceback.format_exc() 45 logging.error(val)
创建一个多文件日志处理, 用到filehandler
1 import logging 2 # 多文件日志处理 3 # 创建⼀个操作⽇志的对象logger(依赖FileHandler) 4 file_handler = logging.FileHandler('l1.log', 'a', encoding='utf-8') 5 # 设置日志文件内容的格式 6 file_handler.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s")) 7 logger1 = logging.Logger('A', level=40) 8 logger1.addHandler(file_handler) 9 # 记录日志 10 logger1.error('我是A系统')
随机生成4位验证码(包含数字, 字母)
1 import random 2 3 lst = [] 4 for i in range(48, 58): 5 lst.append(chr(i)) 6 7 for i in range(ord("a"), ord("z") + 1): 8 lst.append(chr(i)) 9 10 for i in range(ord('A'), ord('Z') + 1): 11 lst.append(chr(i)) 12 13 print(random.sample(lst, 4))
config模块
# 配置就相当于一个大字典,因此可以像字典一样进行操作 import configparser config = configparser.ConfigParser() # 首先是读取文件 config.read("文件名.ini") # 读取配置文件 print(conf.sections()) # 获取所有的章节 指的是配置文件中进行的所有配置的章节即每一块配置的中括号里面的内容, 结果以一个列表的形式展现出来。 # 增删改操作 # 先读取. 然后修改. 最后写回文件 config = configparser.ConfigParser() config.read("db.ini") # 读取文件 # 添加一个章节 # config.add_section("189-DB") # config["189-DB"] = { # "db_ip": "167.76.22.189", # "port": "3306", # "u_name": "root", # "u_pwd": "123456" # } # 修改信息 config.set("168-DB", "db_ip", "10.10.10.168") # 删除章节 config.remove_section("173-DB") # 删除元素信息 config.remove_option("168-DB", "u_name") # 写回文件 config.write(open("db.ini", mode="w"))
发红包案例
1 import random 2 3 4 def red_box(money, n): 5 lst = [] 6 for i in range(n): 7 num = random.randint(1, 10000) 8 lst.append(num) 9 sum_m = sum(lst) 10 percent_lst = [num / sum_m for num in lst] 11 for per in percent_lst: 12 print(round(per * money, 2)) 13 14 15 red_box(200, 10) 16 17 18 # 第二种 生成器版 19 def red_box(money, n): 20 lst = random.sample(range(1, money * 100), n - 1) 21 lst.sort() 22 lst.insert(0, 0) 23 lst.append(money * 100) 24 for index in range(len(lst) - 1): 25 yield (lst[index + 1] - lst[index]) / 100 26 27 28 g = red_box(100, 4) 29 for m in g: 30 print(m)