一、python遇到的坑 【列表中 循环删除】
a=[11,22,33,44,55,66,77] for i in a: if i==33 or i==77: a.remove(i) print(a) #[11, 22, 44, 55, 66] #当要删除的数靠在一起时,出现bug b=[11,22,33,44,55,66,77] for j in b: if j==33 or j==44: b.remove(j) print(b) #[11, 22, 44, 55, 66, 77]
二、用户登录【3次锁定】
"""
目标要求:
1、最多输入3次用户名密码,
2、如果是被锁用户,则一次即退出程序,
3、如果输入正确的用户名密码,则提示登陆成功,程序结束,
4、3次输入不对,会将用户写入被锁用户列表,当然,该用户名需要是在注册用户列表中的。
"""
print("***此程序用于验证用户登录。***")
print("***用户最多可输入3次用户名和密码。***")
print("***输入正确,有提示,不用输满3次,同一个用户名输入错误3次,会被锁***\n")
def checklock(name,lockfile): #检验用户是否被锁定
with open(lockfile,'r',encoding='utf-8')as fd:
lockusernames = fd.readlines()
for lock_name in lockusernames:
if name == lock_name.strip("\n"):
print("用户被锁,请联系管理员")
return True
return False
def checkmatch(name,password,userfile): #检验用户名和密码是否一致
with open(userfile,'r',encoding='utf-8')as fd:
lines=fd.readlines()
for line in lines:
linedate = line.strip("\n").split(":")
if name == linedate[0] and password == linedate[1]:
print("用户名密码正确,登陆成功。")
return True
print("用户名密码不正确。")
return False
def addlockuser(name,userfile,userlockfile): #因为用户输入3次,所有将用户锁定
with open(userfile,'r',encoding='utf-8')as fd1,open(userlockfile,'a',encoding='utf-8')as fd2:
lines=fd1.readlines()
for line in lines:
linedate=line.split(":")
if name==linedate[0]:
fd2.write(name+"\n")
print(name+"被加入被锁用户列表")
return ''
trynum=1
while trynum<=3:
print("第"+str(trynum)+"次输入。")
trynum +=1
name=input("Username: ") #获得用户输入的用户名和密码
password=input("Password: ")
if checklock(name,"lockuser.txt"): #判断输入的用户名是否在被锁用户列表中
break
elif checkmatch(name,password,"user.txt"): #判断是否和存储的用户名密码匹配
break
elif trynum==4: #3次输入不对,加入被锁用户文件
addlockuser(name,"user.txt","lockuser.txt")
break
其中我设置的user.txt和lockuser.text如图所示:。
【注:这边就不放测试的结果了,只要是按照上述的user.txt和lockuser.txt设置文本,使用该代码就可以实现功能】
三、面向对象的小例子
1、烤地瓜
"""
示例属性:
cookedLevel:这是等级描述,0-3表示还是生的,超过3表示半生不熟,超过5表示烤好了,超过8表示烤糊了。当开始烤地瓜的时候,地瓜是生的0。
cookedString:描述地瓜的生熟程度。
condiments:地瓜的配料列表,比如番茄酱、草莓酱等
示例方法:
cook():把地瓜烤一段时间
addCondiments:给地瓜添加配料
__init__()设置默认的属性
__str__() 其必须要有返回值,每次都是打印这个里面的返回值
"""
#知识点:每次烤地瓜的时间是增加的!
class SweetPotato(object):
def __init__(self):
self.cookedLevel=0
self.cookedString='生的'
self.condiments=[]
def __str__(self):
return '地瓜 状态:{},佐料:{}'.format(self.cookedString,self.condiments)
def cook(self,cooked_time):
#因为这个方法被调用了多次,为了能够在每次调用这个方法的时候能够获取到上一次调用这个方法时的cooked_time,需要将cooked_time保存到这个对象的属性中
self.cookedLevel+=cooked_time #因为每次烤地瓜的时间是递加的
if self.cookedLevel>=0 and self.cookedLevel<=3:
self.cookedString='生的'
elif self.cookedLevel>3 and self.cookedLevel<=5:
self.cookedString='半生不熟'
elif self.cookedLevel>5 and self.cookedLevel<=8:
self.cookedString='烤好了'
elif self.cookedLevel>8:
self.cookedString='烤糊了'
def addCondiments(self,item):
self.condiments.append(item)
dg=SweetPotato()
dg.cook(1)
dg.addCondiments('孜然粉')
print(dg)
dg.cook(2)
print(dg)
dg.addCondiments('五香粉')
dg.cook(2)
print(dg)
dg.cook(1)
dg.addCondiments('番茄酱')
print(dg)
结果显示:
""" 地瓜 状态:生的,佐料:['孜然粉'] 地瓜 状态:生的,佐料:['孜然粉'] 地瓜 状态:半生不熟,佐料:['孜然粉', '五香粉'] 地瓜 状态:烤好了,佐料:['孜然粉', '五香粉', '番茄酱'] """
2、存放家具
class Home(object): def __init__(self,new_area,new_info,new_addr): self.area=new_area #房子的总面积 self.info=new_info self.addr=new_addr self.left_area=new_area #房子的可用面积,一开始 可用面积=总面积 self.contain_items=[] def __str__(self): msg="面积:{},户型:{},地址:{}\n".format(self.area,self.info,self.addr) msg+="当前房子的物品有:{}\n".format(self.contain_items) msg+="当前的可用面积:{}".format(self.left_area) return msg def add_item(self,item): #往房子里面加家居 【注:此时的item是一个家居对象】 self.contain_items.append(item.get_name()) self.left_area-=item.get_area() #剩余面积 class Bed(): def __init__(self,new_name,new_area): self.name=new_name self.area=new_area def __str__(self): return "{}占用面积{}".format(self.name,self.area) def get_area(self): return self.area def get_name(self): return self.name fangzi=Home(120,'三室一厅','南京鼓楼') bed1=Bed('席梦思',5) bed2=Bed('蹦蹦床',3) print(bed1) print(bed2) fangzi.add_item(bed1) fangzi.add_item(bed2) print(fangzi)
结果显示:
""" 席梦思占用面积5 蹦蹦床占用面积3 面积:120,户型:三室一厅,地址:南京鼓楼 当前房子的物品有:['席梦思', '蹦蹦床'] 当前的可用面积:112 """
3、实例方法/类方法/静态方法
(1)实例方法:
定义:第一个参数必须是实例对象,该参数名一般约定为“self”,通过它来传递实例的属性和方法(也可以传类的属性和方法);
调用:只能由实例对象调用。
简而言之,实例方法就是类的实例能够使用的方法。这里不做过多解释。
(2)类方法: 使用装饰器@classmethod。
定义:第一个参数必须是当前类对象,该参数名一般约定为“cls”,通过它来传递类的属性和方法(不能传实例的属性和方法);
调用:实例对象和类对象都可以调用。
"""类方法 使用装饰器@classmethod。 原则上,类方法是将类本身作为对象进行操作的方法。假设有个方法,且这个方法在逻辑上采用类本身作为对象来调用更合理,那么这个方法就可以定义为类方法。另外,如果需要继承,也可以定义为类方法。 如下场景:假设我有一个学生类和一个班级类,想要实现的功能为: 执行班级人数增加的操作、获得班级的总人数; 学生类继承自班级类,每实例化一个学生,班级人数都能增加; 最后,我想定义一些学生,获得班级中的总人数。 """ class ClassTest(object): __num = 0 @classmethod def addNum(cls): cls.__num += 1 @classmethod def getNum(cls): return cls.__num # 这里我用到__new__,主要是为了在创建实例的时候调用人数累加的函数。 def __new__(self): ClassTest.addNum() return super(ClassTest, self).__new__(self) class Student(ClassTest): def __init__(self): self.name = '' a = Student() b = Student() print(ClassTest.getNum()) #2
(3)静态方法: 使用装饰器@staticmethod。
定义:参数随意,没有“self”和“cls”参数,但是方法体中不能使用类或实例的任何属性和方法;
调用:实例对象和类对象都可以调用。
"""静态方法 使用装饰器@staticmethod。 静态方法是类中的函数,不需要实例。静态方法主要是用来存放逻辑性的代码,逻辑上属于类,但是和类本身没有关系,也就是说在静态方法中,不会涉及到类中的属性和方法的操作。可以理解为,静态方法是个独立的、单纯的函数,它仅仅托管于某个类的名称空间中,便于使用和维护。 譬如,我想定义一个关于时间操作的类,其中有一个获取当前时间的函数。 """ import time class TimeTest(object): def __init__(self, hour, minute, second): self.hour = hour self.minute = minute self.second = second @staticmethod def showTime(): return time.strftime("%H:%M:%S", time.localtime()) print(TimeTest.showTime()) #16:26:56 t = TimeTest(2, 10, 10) nowTime = t.showTime() print(nowTime) #16:26:56
4、new方法
class Dog(object):
def __new__(cls, *args, **kwargs):
print('__new__方法')
return super(Dog,cls).__new__(cls) #返回对象实例
def __init__(self): #初始化对象
print('__init__方法')
def __str__(self):
return '__str__方法'
def __del__(self):
print('__del__方法')
dog=Dog() #相当于做3件事 1.调用__new__方法来创建对象,并返回该对象 2.__init__方法来初始化对象 3.返回对象的引用
"""结果:
__new__方法
__init__方法
__del__方法
"""
5、单例模式 不管怎么创建,只有一个对象 【若有多个对象,则这些对象其实是一个对象(id相同)】
class SingleMode(object): __instance=None __init_flag=False def __new__(cls, *args, **kwargs): if cls.__instance==None: cls.__instance=object.__new__(cls) #或者super(Dog,cls).__new__(cls) #两个返回的对象相同,只是表达形式不同 return cls.__instance else: return cls.__instance #返回上一次创建对象的引用 def __init__(self,name): if self.__init_flag==False: #只初始化一次 self.name=name self.__init_flag=True a=SingleMode('PSY') print(id(a)) #2213280090936 print(a.name) #PSY b=SingleMode('XK') print(id(b)) #2213280090936 print(b.name) #PSY print(id(a)==id(b)) #True
6、老王开枪 【面向对象的经典应用】
1. 创建老王对象 2. 创建一个枪对象 3. 创建一个弹夹对象 4. 创建一些子弹 5. 创建一个隔壁老宋 6. 老王把子弹安装到弹夹中 7. 老王把弹夹安装到枪中 8. 老王拿枪 9. 老王开枪打隔壁老宋
class Person(object): #人的类 def __init__(self,name): super(Person,self).__init__() self.name=name self.gun=None #用来保存枪对象的引用 self.hp=100 #人的初始血量 def anzhuang_zidan(self, danjia_temp, zidan_temp): #把子弹安装到弹夹中 # 弹夹.保存子弹(子弹) danjia_temp.save_zidan(zidan_temp) def anzhuang_danjia(self, gun_temp, danjia_temp): #把弹夹安装到枪中 # 枪.保存弹夹(弹夹) gun_temp.save_danjia(danjia_temp) def naqiang(self,gun_temp): #拿起一把枪 self.gun=gun_temp def __str__(self): if self.gun: return '{}的血量为:{},他有枪,{}'.format(self.name,self.hp,self.gun) #self.gun就是Gun类中__str__的返回值 else: if self.hp>0: return '{}的血量为:{},他没有枪'.format(self.name,self.hp) else: return '{}已挂'.format(self.name) def koubanji(self,diren): #让枪发射子弹去打敌人 #枪.开火(敌人) self.gun.fire(diren) def loseblood(self,shashangli_temp): #根据杀伤力掉相应的血 self.hp-=shashangli_temp class Gun(object): #枪的类 def __init__(self,name): super(Gun,self).__init__() self.name=name #用来记录枪的类型 self.danjia=None #用来记录弹夹对象的引用 【原来是没有弹夹】 def save_danjia(self,danjia_temp): #将这个子弹保存 self.danjia=danjia_temp def __str__(self): if self.danjia: return '枪信息:{},{}'.format(self.name,self.danjia) #这边self.danjia就是Danjia类中的__str__中的返回 else: return '枪信息:{},这把枪中没有弹夹'.format(self.name) def fire(self,diren): #枪从弹夹中获取一发子弹,然后让子弹去击中敌人 #先从弹夹中取子弹 弹夹.弹出一发子弹() zidan_temp=self.danjia.tanchu() #返回值zidan_temp可能是空,也可能是一发子弹 #让这个子弹去伤害敌人 if zidan_temp: zidan_temp.dazhong(diren) #子弹.打中(敌人) else: print('弹夹中没有子弹......') class Danjia(object): #弹夹类 def __init__(self,max_num): super(Danjia,self).__init__() self.max_num=max_num #用来记录弹夹的最大容量 self.zidan_list=[] #用来记录所有子弹的引用 def save_zidan(self,zidan_temp): #将这个子弹保存 self.zidan_list.append(zidan_temp) def __str__(self): return '弹夹的信息为:{}/{}'.format(len(self.zidan_list),self.max_num) def tanchu(self): #弹出最上面的那颗子弹 if self.zidan_list: return self.zidan_list.pop() else: return None class Zidan(object): #子弹类 def __init__(self,shashangli): super(Zidan,self).__init__() self.shashangli=shashangli #这颗子弹的杀伤力 def dazhong(self,diren): #让敌人掉血 diren.loseblood(self.shashangli) #敌人.掉血(一颗子弹的威力) def main(): #用来控制整个程序的流程 laowang=Person('老王') #1、创建老王对象 ak47=Gun('AK47') #2、创建一个枪对象 danjia=Danjia(20) #3、创建一个弹夹对象 for i in range(15): #4、创建一些子弹 zidan=Zidan(10) laowang.anzhuang_zidan(danjia,zidan) #5、老王把子弹安装到弹夹中 老王.安装子弹到弹夹中(弹夹,子弹) laowang.anzhuang_danjia(ak47,danjia) #6、老王把弹夹安装到枪中 老王.安装弹夹到枪中(枪,弹夹) #test:测试弹夹的信息 #print(danjia) #弹夹的信息为:15/20 #test:测试枪的信息 #print(ak47) #枪信信息:AK47,弹夹的信息为:15/20 laowang.naqiang(ak47) #7、老王拿枪 老王.拿枪(枪) #test:测试老王对象 #print(laowang) #老王的血量为:100,他有枪,枪信息:AK47,弹夹的信息为:15/20 gebi_laosong=Person('隔壁老宋') #8、创建一个敌人 #print(gebi_laosong) #隔壁老宋的血量为:100,他没有枪 laowang.koubanji(gebi_laosong) #9、老王开枪打敌人 老王.扣扳机(隔壁老宋) print(gebi_laosong) #隔壁老宋的血量为:90,他没有枪 print(laowang) #老王的血量为:100,他有枪,枪信息:AK47,弹夹的信息为:14/20 main()