Day.7类与对象

 作业一:总结

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

定义:只要是在类内部定义的,并且没有被任何装饰器修饰过的方法,都是绑定到对象的方法

class Foo:
    def test(self): #绑定到对象的方法
        pass
    def test1(): #也是绑定到对象的方法,只是对象.test1(),会把对象本身自动传给test1,因test1没有参数所以会抛出异常
        pass

调用:对象.对象的绑定方法(),不用为self传值,就是给对象去用

特性:调用时会把对象本身当做第一个参数传给对象的绑定方法

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

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

class Foo:
    @classmethod #把一个方法绑定给类:类.绑定到类的方法(),会把类本身当做第一个参数自动传给绑定到类的方法
    def test(cls,x):
        print(cls,x) #拿掉一个类的内存地址后,就可以实例化或者引用类的属性了

调用:类.类的绑定方法(),不用为cls传值,就是给类去用

特性:调用时会把类本身当做第一个参数传给类的绑定方法

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

定义:在类内部定义的,并且被装饰器@staticmethod修饰过的方法,就是解除绑定的方法,可以说staticmethod就是相当于一个普通的工具包

class Foo:
    def test1(self):
        pass
    def test2():
        pass
    @classmethod
    def test3(cls):
        pass
    @classmethod
    def test4():
        pass
    @staticmethod
    def test5():
        pass
f=Foo()
print(Foo.test1)#<function Foo.test1 at 0x000000B1704AC8C8>
print(Foo.test2)#<function Foo.test2 at 0x000000B1704AC950>
print(Foo.test3)#<bound method Foo.test3 of <class '__main__.Foo'>>
print(Foo.test4)#<bound method Foo.test4 of <class '__main__.Foo'>>
print(Foo.test5)#<function Foo.test5 at 0x000000B1704ACAE8>
print(f.test1)#<bound method Foo.test1 of <__main__.Foo object at 0x000000B1704AE1D0>>
print(f.test2)#<bound method Foo.test2 of <__main__.Foo object at 0x000000B1704AE1D0>>
print(f.test3)#<bound method Foo.test3 of <class '__main__.Foo'>>
print(f.test4)#<bound method Foo.test4 of <class '__main__.Foo'>>
print(f.test5)#<function Foo.test5 at 0x000000B1704ACAE8>

调用:test1与test2都是绑定到对象方法:调用时就是操作对象本身,test3与test4都是绑定到类的方法:调用时就是操作类本身,test5是不与任何事物绑定的:就是一个工具包,谁来都可以用,没有专门操作谁这么一说

特性:不管是类还是对象来调用,都没有自动传值这么一说了

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

定义:在类内部定义的,并且被装饰器@property修饰过的方法,就是类的特性,即property

import math
class Circle:
    def __init__(self,radius):
        self.r=radius
    @property
    def area(self):
        return math.pi*self.r**2
    @property
    def perimeter(self):
        return 2*math.pi*self.r
c=Circle(7)
print(c.r)
print(c.area)
print(c.perimeter)

调用:对象.对象的绑定方法,不用为self传值,也不用加()去运行,直接回返回函数的执行结果,就是给对象去用

意义:在保护隐私,或者隔离复杂度时使用property函数,也就是在封装的情况下。加了装饰器@property的属性还有其余两种方法:@特性名.setter和@特性名.deleter两个装饰器,property的好处就是让使用者以为是在调用类里面的变量,实则是函数,这种特性的使用方式遵循了统一访问的原则,而且被property装饰的属性会优先于对象的属性被使用,还可以设置接口供使用者调用来获取自己需要的数据。

作业二:

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

对于文件的读写操作,可参考:Day5.对文件的增删改查-http://www.cnblogs.com/lxyoung/p/6678765.html

with open('user.db','w') as write_file:
    write_file.write(str({
        "egon":{"password":"123",'status':False,'timeout':0},
        "alex":{"password":"456",'status':False,'timeout':0},
        }))
with open('user.db','r') as read_file:
    data=read_file.read()
    d=eval(data)
    print(d['egon']['password'])# 123
    print(d['egon']['status'])# False
    print(d['egon']['timeout'])# 0

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

class User:
    db_path='user.db'
    def __init__(self,username):
        self.username=username
    @property
    def db(self):
        data=open(self.db_path,'r').read()
        return eval(data)
u1=User('egon')
u2=User('alex')
print(u1.db_path)# user.db
print(u2.db)# {'egon': {'password': '123', 'status': False, 'timeout': 0}, 'alex': {'password': '456', 'status': False, 'timeout': 0}}
print(u1.db[u1.username]["password"])# 123
print(u2.db[u2.username]["password"])# 456

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

import time#导入time模块
class User:#定义User这个类
    db_path='user.db'#定义路径-User类下对象的共有的特性
    def __init__(self,name):#定义User类下对象的独有的特性
        self.name=name#对象独有的名字
    @property#将下面的函数伪装成变量
    def db(self):#定义db-User类下对象的共有的技能
        with open(self.db_path,'r') as read_file:#打开路径文件获得文件句柄
            info=read_file.read()#将读取的文件内容传给info这个变量
            return eval(info)#将info这个字符串类型数据转换为字典类型数据并作为函数的返回值
    @db.setter#实际意义就是修改db这个函数的返回值
    def db(self,value):#因为是修改,所以定义是加一个新的参数
        with open(self.db_path,'w') as write_file:#打开路径文件获得文件句柄,并且是覆盖的方式进行写操作
            write_file.write(str(value))#将新的值赋值给文件的内容
            write_file.flush()#将写入的新内容刷新至文件当中
    def login(self):#定义一个与用户交互的登录函数,可参考:Day5.三次登陆后锁定-http://www.cnblogs.com/lxyoung/p/6678765.html
        data=self.db#实质是调用的@property下边这个函数,并把文件内容给了data这个变量
        if data[self.name]['status']:#判断登陆状态
            print('已经登录')
            return True
        if data[self.name]['timeout'] < time.time():#判断是否超时
            count=0
            while count < 3:#当次数小于3的时候执行下面代码
                passwd=input('password>>: ')
                if not passwd:continue
                if passwd == data[self.name]['password']:
                    data[self.name]['status']=True#若输入正确密码修改登录状态为Ture
                    data[self.name]['timeout']=0#重置时间
                    self.db=data#实质是调用的@db.setter下边这个函数,修改过的data覆盖的写入文件中
                    break
                count+=1
            else:
                data[self.name]['timeout']=time.time()+10#当前时间戳加10秒
                self.db=data
        else:
            print('账号已经锁定10秒')
u1=User('egon')
u1.login()
u1.login()#将密码正确输入,执行结果为已经登录。打开下面代码的注释并执行,将密码错误输入三次后,获得执行结果
# time.sleep(5)
# u1.login()
# time.sleep(6)
# u1.login()

执行结果如下:

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

import time
class User:
    db_path='user.db'
    def __init__(self,name):
        self.name=name
    @property
    def db(self):
        with open(self.db_path,'r') as read_file:
            info=read_file.read()
            return eval(info)
    @db.setter
    def db(self,value):
        with open(self.db_path,'w') as write_file:
            write_file.write(str(value))
            write_file.flush()
    @property
    def checktime(self):
        data = self.db
        print("您的用户还有%s秒解锁"%(data[self.name]['timeout']-time.time()))
    def login(self):
        data=self.db
        if data[self.name]['status']:
            print('已经登录')
            return True
        if data[self.name]['timeout'] < time.time():
            count=0
            while count < 3:
                passwd=input('password>>: ')
                if not passwd:continue
                if passwd == data[self.name]['password']:
                    data[self.name]['status']=True
                    data[self.name]['timeout']=0
                    self.db=data
                    break
                count+=1
            else:
                data[self.name]['timeout']=time.time()+10
                self.db=data
        else:
            print('账号已经锁定10秒')
    def userexit(self):
        data = self.db
        if data[self.name]['status']:
            data[self.name]['status'] = False
            self.db = data
            print("成功退出登录")
        else:
            print("无法退出,您当前没有登录")
u1=User('egon')
# u1.login()
# u1.login()
# u1.userexit()
# u1.userexit()
# u1.login()
u1.login()
u1.login()
u1.checktime
time.sleep(3)
u1.checktime

 

 



posted @ 2017-04-22 17:13  这个新手不太冷°  阅读(142)  评论(0编辑  收藏  举报