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特性 使用的主要内容,如果未能解决你的问题,请参考以下文章