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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python基础 ---- property特性 使用相关的知识,希望对你有一定的参考价值。

作业一:总结

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()

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






以上是关于python基础 ---- property特性 使用的主要内容,如果未能解决你的问题,请参考以下文章

Python的特性(property) (转)

python 旧类中使用property特性的方法

Python的特性(Property)和描述符

Python-类的特性(property)

Python 面向对象 之 @property

python 之用装饰器@property,把方法变成一个特性