python基础 ---- property特性 使用

时间:2021-02-18 18:41:09

作业一:总结

1.什么是绑定到对象的方法,如何定义,如何调用,给谁用?有什么特性
  1.1 绑定到对象的方法:只要是在类内部定义的,没有被装饰器装饰过的方法,都是绑定到对象的。
  1.2 调用 :对象.对象的绑定方法,
  1.3 给谁用:给对象用
  1.4 特性 : (自动传值)调用时会把对象本身当做第一个参数自动传给绑定到对象方法

1 class Foo: 2     def test(self):   #绑定到对象的方法
3         print("hello world") 4     def test1():  # 绑定到对象的方法,test1本身没有参数,调用时把对象本身自动传给test1,
5                   # test1没有参数,会抛出不需要参数,但是给了一个参数的错误
6         print("hello friend") 7 msg = Foo()  #把Foo类 实例化为msg对象
8 msg.test()   #使用方法 ,msg.test() , msg是对象,test()是msg的绑定方法,调用时,把msg自动传给self
9 #msg.test1() # 调用

2.什么是绑定到类的方法,如何定义,如何调用,给谁用?有什么特性

  2.1  绑定到类的方法:在类内部定义的,被@classmethod装饰器修饰过的方法,都是绑定到类的方法

  2.2 调用 :1)类名.绑定到类的方法 2)对象.绑定到对象的方法, 都可以调用

  2.3 给谁用:给类本身用,也可以给对象用

  2.4 特性:(自动传值)调用时会把类本身当做第一个参数自动传给绑定到类的方法

 1 class Foo:  2     def test(self):   #绑定到对象的方法
 3         print("hello world")  4 
 5     @classmethod   #把一个方法绑定给类
 6     def test1(cls):  # 绑定到类的方法,
 7         print("hello friend")  8 msg = Foo()  #把Foo类 实例化为msg对象
 9 msg.test1()   #使用方法 ,msg.test1() , msg是对象,test1()是msg的绑定方法,调用时,把msg自动传给self
10 Foo.test1()   #使用方法,Foo.test1(),Foo是类名,test1()是类的绑定方法,调用时会把Foo本身传给cls
11 # msg.test1() ,Foo.test1(),都是在调用类的绑定方法,结果是一样的

3.什么是解除绑定的函数,如何定义,如何调用,给谁用?有什么特性

  3.1 解除绑定的方法:在类内部定义的,使用@staticmethod装饰器修饰过的,就是解除绑定对象的函数方法

  3.2 特性:无论是类 或者对象,调用时 就不自动传值了,@staticmethod就是相当于一个普通的工具包

  3.3 既不与类绑定,也不与对象绑定,相当于一个普通的函数,对象可以用,类也可以用

 1 class Foo:  2     def test(self,name):  #绑定到对象的方法
 3         print("hello %s" %(name))  4     @classmethod    #绑定到类的方法
 5     def test1(cls,name):  6         print("hello %s" %(name))  7     @staticmethod   #解除绑定的方法, 这时test2 就是一个普通的函数,既不与类绑定,也不与对象绑定
 8     def test2(name):  9         print("hello %s" %(name)) 10 msg = Foo() 11 msg.test("alex")  # 绑定到对象的方法:自动把msg这个对象传给self,alex传给name了
12 Foo.test1("egon")  # 绑定到类的方法:自动把Foo这个类名传给cls,egon传给name了
13 msg.test2("瞎驴")   #对象.test2 :把瞎驴传给name,test2有几个参数,就需要传几个参数
14 Foo.test2("钢弹")   #类.test2 :把钢弹传给name

4.什么是property,如何定义,如何使用,给谁用,什么情况下应该将一个属性定义成property,有什么好处?

  4.1 property是一个内置函数,在类内部的方法上,加上@property装饰器,name这个方法就变成一个属性了

  4.2 用法:@property   在类,或者可调用对象上面加上@property

  4.3 被@property装饰器装饰过的属性,在被调用时,会优先于对象的属性被使用,

  4.4 好处:对于使用者来说,把访问方法统一了,封装,把真实的逻辑伪装起来了,让使用者以为就是用的就是数据属性,美化程序

  

 1 class People:  2     '''计算BMI值'''
 3     def __init__(self,name,age,height,weight):  4         '''初始化name,age,height,weight'''
 5         self.name = name  6         self.age = age  7         self.height = height  8         self.weight = weight  9  @property 10     def boyindex(self): 11         BMI = self.weight/(self.height**2) 12         if BMI < 18.5: 13             print("体重过轻") 14         elif BMI < 24 and BMI >=18.5: 15             print("正常范围") 16         elif BMI > 24: 17             print("体重超重") 18         return BMI 19 
20 s1 = People("egon",25,1.75,56) 21 print(s1.boyindex)   #调用property修饰过的boyindex
22 #执行结果
23 # 体重过轻
24 # 18.285714285714285

 4.5 使用property 延伸出,setter,deletle  ,后面这俩函数,使用的时候需要加上被property修饰了的方法名

 1 #被property 装束的属性 会优先于对象属性被使用
 2 # 而被property装饰的属性,如sex分为三种
 3 # 1,@property 查看
 4 # 2,@sex.setter 修改
 5 # 3,@sex.deleter 删除
 6 
 7 class People:  8     def __init__(self,name,sex):  9         self.name = name 10         self.__sex = sex 11 
12     @property  #查看
13     def sex(self): 14         return self.__sex
15 
16     @sex.setter  #修改
17     def sex(self,value): 18         if not isinstance(value,str): 19             raise TypeError("sex is str")  #主动抛出异常
20         self.__sex = value 21 
22     @sex.deleter  #删除
23     def sex(self): 24         del self.__sex
25 
26 p1 = People("egon","male") 27 print(p1.sex)  #执行结果: male 调用的@property下的sex
28 p1.sex = "female"  # 把sex初始化的male修改成female
29 print(p1.sex)  #执行结果:female 调用@sex.seltter下的sex
30 del p1.sex    # 删除 __sex 
31 print(p1.sex)   #结果:报错,因为已经把__sex删除了,所以找不到
32                 # AttributeError: 'People' object has no attribute '_People__sex'

作业二:

要求一:自定义用户信息数据结构,写入文件,然后读出内容,利用eval重新获取数据结构

 1 #要求一:自定义用户信息数据结构,写入文件,然后读出内容,利用eval重新获取数据结构
 2 
 3 with open('user.db','w') as write_file:  #以覆盖写的模式打开user.db文件,存储到write_file变量中
 4  write_file.write(str({  5         "egon":{"password":"123",'status':False,'timeout':0},  6         "alex":{"password":"456",'status':False,'timeout':0},  7         }))  #把上述内容以字符串格式写入到write_file文件中,保存 关闭文件
 8 
 9 with open('user.db','r') as read_file: # 以的读的模式打开user.db文件,存储到read_file变量中
10     data=read_file.read()     #读取文件的全部内容
11     d=eval(data)              # 把字符串转化为dict类型
12     print(d['egon']['password'])   #123
13     print(d['egon']['status'])     #Flase
14     print(d['egon']['timeout'])    #0

要求二:定义用户类,定义属性db,执行obj.db可以拿到用户数据结构

 1 class User:  2     '''查看用户信息'''
 3     db_path = "user.txt"  #只是把文件存到变量中,什么都没干
 4     def __init__(self,user_name,):  5         '''初始化用户名字'''
 6         self.name = user_name  7 
 8     @property      #修饰db,变成数据属性
 9     def db(self): 10         data = open(self.db_path,"r").read()   #打开db_path变量中的文件,读取文件
11         d = eval(data)   #把文件内容转换成dict数据类型
12         return d 13         data.close()      #关闭文件
14 
15 e = User("egon",) 16 a = User("alex") 17 print("%s data :"%(e.name)) 18 print(e.db["egon"]) 19 print("%s data :"%(a.name)) 20 print(a.db["alex"])

 

要求三:分析下述代码的执行流程

 

 1 import time  #导入时间模块
 2 
 3 
 4 class User_login:  5     '''锁定用户,限制时间登录'''
 6     user_path = "user.txt"
 7     def __init__(self,user_name):  8         self.name = user_name  9 
10  @property 11     def tall_user(self):        #查看锁定时间
12         with open("user.txt","r") as f: 13             data = f.read() 14             data = eval(data) 15             ti = int(data[self.name]["timeout"]-time.time())# dict中的时间减去当前时间就是剩下多少秒才可以登陆
16             if ti <= 0: 17                 ti = 0 18                 return ("%s 用户锁定时间还剩%s秒,可以登陆" %(self.name,ti)) 19             else: 20                 return ("%s 用户锁定时间还剩%s秒" %(self.name,ti)) 21 
22     @property          #把下面db方法改成 数据属性
23     def db(self): 24         with open(self.user_path,"r") as read_file: 25             info = read_file.read()   #读取文件
26             return eval(info)     #返回dict类型
27     @db.setter    # 修改属性
28     def db(self,value): 29         with open(self.user_path,"w") as write_file: 30             write_file.write(str(value))    # 把下面传来的value 写入到文件
31             write_file.flush()    #刷新文件
32 
33     def login(self): 34         '''登录方法'''
35         data = self.db    #把当前文件内dict的数据存到data中
36         if data[self.name]["status"] is True:  # 判断 用户名下的status的value是否为True
37             print("%s 用户已经登录"%(self.name)) 38             return True       #返回True
39 
40         if data[self.name]["timeout"] < int(time.time()):  #判断当前时间是否小于字典中的时间
41             count = 0   #为下面循环 添加一个计数器
42             while count < 3:  #进入主循环 ,循环3次
43                 password = input("please your input password :")  #输入密码
44                 if not password:   #不是字典中的密码,返回循环
45                     continue
46                 if password == data[self.name]["password"]:  #判断输入的密码能否跟文件中的密码匹配匹配上
47                     print("%s 用户登陆成功"%(self.name)) 48                     data[self.name]["status"] = True   #把字典中status的False改为True
49                     data[self.name]["timeout"] = 0     #把字典中的时间改为0
50                     self.db = data          # 把 改完的数据 在重新返回给self.db
51                     break        #跳出循环
52                 count += 1   # 前面都没匹配上 ,循环次数加1
53 
54             else: 55                 print("密码错误,账号锁定100秒")    # 走到这里 说明前面都没匹配上
56                 data[self.name]["timeout"] = int(time.time())+100  #把字典中时间加上100秒
57                 self.db = data   # 把data数据重新传给self.db
58         else: 59             print("账户已锁定") 60 
61 
62 
63 
64 
65 66 a = User_login("egon") 67 a.login() 68 #print(a.tall_user)
69

要求四:根据上述原理,编写退出登录方法(退出前要判断是否是登录状态),自定义property,供用户查看自己账号的锁定时间

 1 import time  #导入时间模块
 2 
 3 
 4 class User:  #定义用户类 ,父类
 5     '''锁定用户,限制时间登录'''
 6     user_path = "user.txt"
 7     def __init__(self,user_name):  8         self.name = user_name  9 
 10  @property  11     def tall_user(self):        #查看锁定时间
 12         with open("user.txt","r") as f:  13             data = f.read()  14             data = eval(data)  15             ti = int(data[self.name]["timeout"]-time.time())# dict中的时间减去当前时间就是剩下多少秒才可以登陆
 16             if ti <= 0:  17                 ti = 0  18                 return ("%s 用户锁定时间还剩%s秒,可以登陆" %(self.name,ti))  19             else:  20                 return ("%s 用户锁定时间还剩%s秒" %(self.name,ti))  21 
 22     @property          #把下面db方法改成 数据属性
 23     def db(self):  24         with open(self.user_path,"r") as read_file:  25             info = read_file.read()   #读取文件
 26             return eval(info)     #返回dict类型
 27     @db.setter    # 修改属性
 28     def db(self,value):  29         with open(self.user_path,"w") as write_file:  30             write_file.write(str(value))    # 把下面传来的value 写入到文件
 31             write_file.flush()    #刷新文件
 32 
 33 class User_login(User):  #定义用户登录类,子类,继承了User父类
 34 
 35     pass
 36 
 37     def login(self):  38         '''登录方法'''
 39         data = self.db    #把当前文件内dict的数据存到data中
 40         if data[self.name]["status"] is True:  # 判断 用户名下的status的value是否为True
 41             print("用户%s已经登录".center(50,"-")%(self.name))  42 
 43             return True       #返回True
 44 
 45         if data[self.name]["timeout"] < int(time.time()):  #判断当前时间是否小于字典中的时间
 46             count = 0   #为下面循环 添加一个计数器
 47             while count < 3:  #进入主循环 ,循环3次
 48                 password = input("please your input password :")  #输入密码
 49                 if not password:   #不是字典中的密码,返回循环
 50                     continue
 51                 if password == data[self.name]["password"]:  #判断输入的密码能否跟文件中的密码匹配匹配上
 52                     print("用户 %s 登陆成功".center(50,"-")%(self.name))  53                     print("welocome to %s ".center(55, "-") % (self.name))  54                     data[self.name]["status"] = True   #把字典中status的False改为True
 55                     data[self.name]["timeout"] = 0     #把字典中的时间改为0
 56                     self.db = data          # 把 改完的数据 在重新返回给self.db
 57                     break        #跳出循环
 58                 count += 1   # 前面都没匹配上 ,循环次数加1
 59 
 60             else:  61                 print("密码错误,账号锁定100秒")    # 走到这里 说明前面都没匹配上
 62                 data[self.name]["timeout"] = int(time.time())+100  #把字典中时间加上100秒
 63                 self.db = data   # 把data数据重新传给self.db
 64         else:  65             print("账户已锁定")  66 
 67 class User_out(User):  #定义用户退出类,子类,继承了User父类
 68 
 69     pass
 70 
 71     def out(self):  72         '''退出方法'''
 73         data = self.db  74         while True:  75             print("您是要退出吗?")  76             choice = input("exit please input 'q':")  77 
 78             if choice.isdigit():  79                 print("\n please not input number\n")  80                 continue
 81             if data[self.name]["status"] is True:  82                 if choice == "q":  83                     data[self.name]["status"] = False  84                     self.db = data  85                     print("记得再来啊".center(50,"-"))  86                     print("bye bye %s".center(50,"-")%(self.name))  87                     break
 88                 else:  89                     print("看来你还想在玩玩")  90                     continue
 91             else:  92                 if data[self.name]["status"] is False:  93                     print("用户没有登录, 请先登录")  94                     break
 95 
 96 l = User_login("egon")  97 o = User_out("egon")  98 print(l.tall_user)  99 l.login() 100 #o.out()

感慨:做作业花了快一天的时间了,从中午十二点,到现在快晚上十二点了,终于是做出来了,好高兴啊,继续努力,加油,坚持,坚持,在坚持