作业一:总结
1.什么是绑定到对象的方法,如何定义,如何调用,给谁用?有什么特性
2.什么是绑定到类的方法,如何定义,如何调用,给谁用?有什么特性
3.什么是解除绑定的函数,如何定义,如何调用,给谁用?有什么特性
1 # 1. 2 #在类中定义的(self)方法都是绑定到对象的方法 3 #定义 4 class 人: 5 def 中国人(self):#绑定到对象的方法 6 pass 7 #调用: 8 c = 人() #实例化 9 c.中国人()#调用对象,传参 10 11 # 2. 12 #静态方法和类方法都是绑定到类的方法 13 #静态方法定义: 14 class 类的静态函数: 15 @staticmethod#调用装饰器staticmethod 16 def 静态函数():#静态方法 17 pass 18 #调用: 19 类的静态函数.静态函数()#不用实例化直接类函数名.就可以调用静态方法,静态方法是让类去调用的方法 20 21 22 #类方法定义: 23 class 类函数: 24 @classmethod#定义类方法,需要调用装饰器classmethod 25 def 类的方法(cls):#被classmethod修饰过的类的方法就是一个类方法 26 pass 27 #调用: 28 类函数.类的方法()#不用实例化直接类函数名.就可以调用类方法 29 #类方法是与类绑定的方法,也给类调用的方法 30 #当类调用类方法时,会将当前调用方法的类当做第一个参数传递到方法中 31 # 3.什么是解除绑定的函数,如何定义,如何调用,给谁用?有什么特性 32 #定义在类的内部,并且被staticmethod修饰过的方法 33 #定义: 34 class 不带功能: 35 @staticmethod 36 def 不带(a,b,c): 37 pass 38 #调用: 39 没有功能 = 不带功能.不带(1,2,3) 40 #or: 41 没功能 = 不带功能() 42 没功能1 = 没功能.不带(1,2,3) 43 #解除绑定方法不在自动传值
4.什么是property,如何定义,如何使用,给谁用,什么情况下应该将一个属性定义成property,有什么好处?
1 #什么propert? 2 class 属性类: 3 def __init__(自身, 取=None, 赋=None, 删=None): 4 自身.取 = 取 5 自身.赋 = 赋 6 自身.删 = 删 7 8 def __get__(自身, 触发者, 所有者): 9 return 自身.取(触发者) 10 11 def __set__(自身, 触发者, 值): 12 自身.赋(触发者, 值) 13 14 def __delete__(自身, 触发者): 15 自身.删(触发者) 16 17 18 class C: 19 def __init__(自身): 20 自身._x = None 21 22 def 取(自身): 23 return 自身._x 24 25 def 赋(自身, 值): 26 自身._x = 值 27 28 def 删(自身): 29 del 自身._x 30 31 x = 属性类(取, 赋, 删) 32 33 34 if __name__ == '__main__': 35 c = C() 36 print(c.x) 37 c.x = 'X=man' 38 print(c.x) 39 print(c._x) 40 del c.x 41 #一般在__属性的情况下使用property,这样可以有效的隐藏,展示,控制__属性对用户的影响
如何定义,如何使用,给谁用,什么情况下应该将一个属性定义成property,有什么好处?
property(fget=None, fset=None, fdel=None, doc=None)
条条大路通罗马,同样是完成一件事,Python 其实提供了好几个方式供你选择。
property() 是一个比较奇葩的BIF,它的作用把方法当作属性来访问,从而提供更加友好访问方式。
官方帮助文档代码:
1 class C: 2 def __init__(self): 3 self._x = None 4 5 def getx(self): 6 return self._x 7 def setx(self, value): 8 self._x = value 9 def delx(self): 10 del self._x 11 x = property(getx, setx, delx, "I'm the 'x' property.")
property() 返回一个可以设置属性的属性,当然如何设置属性还是需要我们人为来写代码。第一个参数是获得属性的方法 名(例子中是 getx),
第二个参数是设置属性的方法名(例子中是 setx),第三个参数是删除属性的方法名(例子中是 delx)。
property() 有什么作用呢?举个例子,在上边的例题中,我们为用户提供 setx 方法名来设置 _x 属性,
提供 getx 方法名来 获取属性。但是有一天你心血来潮,突然想对程序进行大改,可能你需要把 setx 和
getx 修改为 set_x 和 get_x,那你不得 不修改用户调用的接口,这样子的体验就非常不好。
有了 property() 所有问题就迎刃而解了,因为像上边一样,我们为用户访问 _x 属性只提供了 x 属性。
无论我们内部怎么改 动,只需要相应的修改 property() 的参数,用户仍然只需要去操作 x 属性即可,对他们来说没有任何影响。
使用属性修饰符创建描述符
使用属性修饰符创建描述符,也可以实现同样的功能.
官方帮助文档代码:
1 class C: 2 def __init__(self): 3 self._x = None 4 5 @property 6 def x(self): 7 """I'm the 'x' property.""" 8 return self._x 9 10 @x.setter 11 def x(self, value): 12 self._x = value 13 14 @x.deleter 15 def x(self): 16 del self._x
注意:三个处理 _x 属性的方法名要相同(参数不同)。
要求二:定义用户类,定义属性db,执行obj.db可以拿到用户数据结构
1 #要求一:自定义用户信息数据结构,写入文件,然后读出内容,利用eval重新获取数据结构 2 with open('user.db','w') as write_file:#创建并以写入的方式打开一个文件user.db 3 write_file.write(str({ 4 "egon":{"password":"123",'status':False,'timeout':0}, 5 "alex":{"password":"456",'status':False,'timeout':0}, 6 }))#在user.db中加入两个用户信息以字典的方式储存 7 8 with open('user.db','r') as read_file:#以只读的方式打开一个文件user.db 9 data=read_file.read()#读取user.db中的数据 10 d=eval(data)#将user.db中的数据转为字典 11 print(d['egon']['password'])#打印字典中egon的password 对应value 12 print(d['egon']['status']) 13 print(d['egon']['timeout']) 14 15 定义文件结构 16 #要求二:定义用户类,定义属性db,执行obj.db可以拿到用户数据结构 17 class User: #定义User类 18 db_path='user.db' 19 def __init__(self,username): #在实例化User类时,传入Username参数的值 20 self.username=username 21 @property#将db()方法作为属性,让用户调用 22 def db(self): 23 data=open(self.db_path,'r').read()#以只读的方式打开文件user.db 24 return eval(data)#以字典的方式返回user.db中的内容 25 u=User('egon')#实例化对象u,传入egon 26 print(u.db['egon'])#打印又u.db()返回的字典中,对应egon的value 27 print(u.db['egon']['password'])#打印又u.db()返回的字典中,对应egon的password,value 28 29 获取用户信息
要求三:分析下述代码的执行流程
1 #要求三:分析下述代码的执行流程 2 import time 3 class User:#定义User类 4 db_path='user.db' 5 def __init__(self,name): #在实例化User类时,传入name参数的值 6 self.name=name 7 @property#将db()方法作为属性,让用户调用,同时产生db.setter和db.del方法 8 def db(self): 9 with open(self.db_path,'r') as read_file:#当调用db方法时,打开文件user.db 10 info=read_file.read() 11 return eval(info)#以字典的方式返回user.db中的用户信息 12 @db.setter#在对db属性进行修改操作的时候,调用此方法 13 def db(self,value): 14 with open(self.db_path,'w') as write_file:#创建并打开一个文件user.db 15 write_file.write(str(value))#在文件中写入db属性得到的值 16 write_file.flush()#刷新文件的缓冲区域,让数据立刻写入文件 17 def login(self): #定义login方法 18 data=self.db#data得到db方法(现在被@property修饰过的属性)返回的user.db中的数据 19 if data[self.name]['status']:#判断name的status字段是否为Ture 20 print('已经登录') 21 return True 22 if data[self.name]['timeout'] < time.time(): #判断name的timeout字段值是否小于....呃~1970年到现在的时间 23 count=0 24 while count < 3: 25 passwd=input('password>>: ')#输入密码 26 if not passwd:continue#如果密码为空,那么重新循环到输入密码 27 if passwd == data[self.name]['password']: #输入密码正确 28 data[self.name]['status']=True#更改用户的登陆状态 29 data[self.name]['timeout']=0#超时字段归0 30 self.db=data#将改写过的值重新调用db.setter方法存入user.db文件中,在用户看来就是对db属性进行了重新的赋值操作 31 break 32 count+=1#只允许用户输入三次错误的机会 33 else: 34 data[self.name]['timeout']=time.time()+10#如果三次输入错误,那么该用户将被锁定10秒 35 self.db=data#将改写过的值重新调用db.setter方法存入user.db文件中,在用户看来就是对db属性进行了重新的赋值操作 36 else:#如果判断用户的timeout大于1970年到现在的值 37 print('账号已经锁定10秒') 38 39 u1=User('egon') #实例化u1传入name,egon 40 print("egon login:") 41 u1.login()#u1调用login的方法
要求四:根据上述原理,编写退出登录方法(退出前要判断是否是登录状态),自定义property,供用户查看自己账号的锁定时间
1 #要求四:根据上述原理,编写退出登录方法(退出前要判断是否是登录状态),自定义property,供用户查看自己账号的锁定时间 2 import time 3 class User:#定义User类 4 db_path='user.db' 5 def __init__(self,name): #在实例化User类时,传入name参数的值 6 self.name=name 7 print("%s Login:"%self.name) 8 @property#将db()方法作为属性,让用户调用,同时产生db.setter和db.del方法 9 def db(self): 10 with open(self.db_path,'r') as read_file:#当调用db方法时,打开文件user.db 11 info=read_file.read() 12 return eval(info)#以字典的方式返回user.db中的用户信息 13 @db.setter#在对db属性进行修改操作的时候,调用此方法 14 def db(self,value): 15 with open(self.db_path,'w') as write_file:#创建并打开一个文件user.db 16 write_file.write(str(value))#在文件中写入db属性得到的值 17 write_file.flush()#刷新文件的缓冲区域,让数据立刻写入文件 18 @property 19 def UserLockTime(self): 20 return int(self.db[self.name]["timeout"]-time.time()) 21 def loginOut(self): 22 data = self.db 23 if(data[self.name]['status']): 24 print(self.name, "正在登出.....") 25 data[self.name]['status'] = False 26 self.db = data 27 time.sleep(2) 28 print(self.name,"登出成功!") 29 else: 30 print(self.name,"并没有登陆") 31 def login(self): #定义login方法 32 data=self.db#data得到db方法(现在被@property修饰过的属性)返回的user.db中的数据 33 if data[self.name]['status']:#判断name的status字段是否为Ture 34 print('已经登录') 35 return True 36 if data[self.name]['timeout'] < time.time(): #判断name的timeout字段值是否小于....呃~1970年到现在的时间 37 count=0 38 while count < 3: 39 passwd=input('password>>: ')#输入密码 40 if not passwd:continue#如果密码为空,那么重新循环到输入密码 41 if passwd == data[self.name]['password']: #输入密码正确 42 data[self.name]['status']=True#更改用户的登陆状态 43 data[self.name]['timeout']=0#超时字段归0 44 self.db=data#将改写过的值重新调用db.setter方法存入user.db文件中,在用户看来就是对db属性进行了重新的赋值操作 45 print("欢迎%s登陆,马上为您进行登出服务"%self.name) 46 time.sleep(3) 47 break 48 count+=1#只允许用户输入三次错误的机会 49 else: 50 data[self.name]['timeout']=time.time()+20#如果三次输入错误,那么该用户将被锁定20秒 51 self.db=data#将改写过的值重新调用db.setter方法存入user.db文件中,在用户看来就是对db属性进行了重新的赋值操作 52 else:#如果判断用户的timeout大于1970年到现在的值 53 print('账号已经锁定20秒,剩余%s秒'%self.UserLockTime) 54 u1=User('egon') #实例化u1传入name,egon 55 u1.login()#u1调用login的方法 56 u1.loginOut()#u1调用loginOut方法 57 u2=User('alex') 58 u2.login() 59 60 三次登陆Property功能升级版