• 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


  • 相关阅读:
    URL重定向功能与APS.NET的固化功能结合
    How can I share types when generate WebSevice proxies using local paths
    C# Coding Standard Naming Conventions and Style
    VS自动化对象模型
    odac 如何捕捉错误odac 如何捕捉错误
    webbrower应用实例
    webbrower在同一个窗口打开新增窗口
    [DELPHI]$2501錯誤處理
    暴力破解例子
    webbrower连接在新form中显示
  • 原文地址:https://www.cnblogs.com/lxyoung/p/6747622.html
Copyright © 2020-2023  润新知