• 爱根,property练习和staticmethod及classmethod总结


    # 作业一:总结
    # 1.什么是绑定到对象的方法,如何定义,如何调用,给谁用?有什么特性?
    ########################################################################################################################
    #     绑定到对象的方法:对象/实例本身只有数据属性,但是python的class机制会将类的函数绑定到对象上,称为对象的方法,或者叫绑定方法。
    #     如何定义:在类中定义相应的函数,而且函数的参数中必须要有 self 参数,代表绑定在 object 对象上。
    #     如何调用,给谁用:对象.函数名(self#代表将self对象自己传进去),然后就会执行。自然绑定到对象的方法是给对象来用。
    #     有什么特性:对象的绑定方法的特别之处在于:obj.func()会把obj传给func的第一个参数。
    #举例:
    # class A:
    #     def a(self):
    #         print("I love egon forever!")
    # p=A()
    # q=A()
    # print(p.__dict__,q.__dict__)
    # print(A.__dict__)
    # print(p.a)          #<bound method A.a of <__main__.A object at 0x0000000001EAD0B8>>
    # print(q.a)          #<bound method A.a of <__main__.A object at 0x0000000001EAD5C0>>
    #                     #绑定方法唯一绑定一个对象,同一个类的方法绑定到不同的对象上,属于不同的方法,内存地址都不会一样。
    # print(A.a)          #<function A.a at 0x00000000021DF730>
    # p.a()               #I love egon forever!
    ########################################################################################################################
    #     2.什么是绑定到类的方法,如何定义,如何调用,给谁用?有什么特性
    #     绑定到类的方法:类的方法是给类用的,类在使用时会将类本身当作参数传给类方法的第一个参数。
    #     如何定义:Python内置了函数classmethod来把类中的函数定义成类的方法。
    #     如何调用,给谁用: 类名.方法名(cls#将调用者自动传入,即子类=cls),因为是类调用的绑定方法,即调用的那个类用该方法实例化。给类用。
    #     有什么特性:类在使用时会将类本身当作参数传给类方法的第一个参数。
    # 举例:
    # class A:
    #     @classmethod
    #     def a(cls):
    #         print("I love egon forever!")
    #         return cls()
    # class B(A):
    #     pass
    # b=B.a()
    # print(b)    #<__main__.B object at 0x00000000021CD5C0>  子类B调用的是父类A的绑定方法,但是实例b却是由子类B生成的。
    ########################################################################################################################
    # 3.什么是解除绑定的函数,如何定义,如何调用,给谁用?有什么特性
    #       什么是解除绑定的函数:但凡是定义在类的内部,并且被staticmethod装饰器修饰过的方法,都是解除绑定的方法。
    #       如何定义:位于类定义的命名空间中,不会对任何实例类型进行操作,python为我们内置了函数staticmethod来把类中的函数定义成静态方法。
    #       如何调用:类/对象.函数名(),来直接生成实例或调用函数。
    #       特性:没有任何自动传值的功能。
    #举例:
    # class Forever:
    #     def __init__(self,name,age):
    #         self.name=name
    #         self.age=age
    #     @staticmethod
    #     def love():
    #         return Forever("egon","17 year old rainy season ")
    # lover=Forever.love()
    # print(lover)             #<__main__.Forever object at 0x000000000222D668>
    # print(lover.__dict__)    #{'name': 'egon', 'age': '17 year old rainy season '}
    # 4.什么是property,如何定义,如何使用,给谁用,什么情况下应该将一个属性定义成property,有什么好处?
    ########################################################################################################################
    #       什么是property,如何定义,如何使用,给谁用:property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值,使用的时候直接
    #       obj.func,但是这个func必须是在property装饰下才能这么直接调用的。这是给对象调用的,只不过伪装成了一个对象的数据属性,其实是执行
    #       了一段函数。
    #       什么情况下应该将一个属性定义成property,有什么好处:将一个类的函数定义成特性以后,对象再去使用的时候obj.func,根本无法察觉自己的
    #       func是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则,与obj.func()完全不同。
    #举例:
    # 1、
    # import math
    # class Gen:
    #     def __init__(self,length,diameter):
    #         self.length=length
    #         self.diameter=diameter
    #         self.volume=length*math.pi*((diameter/2)**2)
    # egon=Gen(180,100)
    # print(egon.volume)
    # 2、
    # class Gen:
    #     def __init__(self,length,diameter):
    #         self.length=length
    #         self.diameter=diameter
    #     @property
    #     def volume(self):
    #         return self.length*math.pi*((self.diameter/2)**2)
    # egon=Gen(180,100)
    # print(egon.volume)
    # print(Gen.volume)       #<property object at 0x0000000001DB8318>  可以发现类无法调用property了,已经成为对象的专属数据属性了。
    # print(Gen.volume(egon))
    # 3、
    # class Gen:
    #     def __init__(self,length,diameter):
    #         self.length=length
    #         self.diameter=diameter
    #     def volume(self):
    #         return self.length*math.pi*((self.diameter/2)**2)
    # egon=Gen(180,100)
    # print(egon.volume())
    # 可以通过以上三个例子说明:加了property装饰器的在类下面定义的函数,可以直接作为对象的数据属性类调用。
    ########################################################################################################################
    # 作业二:
    # 要求一:自定义用户信息数据结构,写入文件,然后读出内容,利用eval重新获取数据结构
    # with open('user.db','w') as write_file: #以覆盖写的方式创建”user.db",没有该文件的话,自己创建。
    #     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)                        #读取出来的也是字符串,所以需要转化为字典才能提取key。
    #     print(d['egon']['password'])
    #     print(d['egon']['status'])
    #     print(d['egon']['timeout'])
    ########################################################################################################################
    
    # # 要求二:定义用户类,定义属性db,执行obj.db可以拿到用户数据结构      #以下文件中内容为自我修改的。
    # class User:                       #{"yuan":{"age":16,"sex":"lang","password":519},"egon":{"age":17,"sex":"mid",
    #     db_path = 'user.db'           # "password":520},"alex":{"age":18,"sex":"none","password":521}}#"user.db"文件中的内容。
    #     def __init__(self,username):            #User类的内置函数,传入username参数,后面引用。
    #         self.username=username              #定义self的数据属性,obj.username
    #     @property                               #加装饰器。
    #     def db(self):                           #定义db函数,将其加装饰器后实际就成了obj的数据属性了,只不过默默执行了函数。
    #         data=open(self.db_path,'r').read()  #打开self.db_path,因为self自己里面没有,所以到类里找到了“user.db",限定这一类统一
    #         print(type(data))                   #使用”user.db"。
    #         return eval(data)                   #由于读取到的是str格式,所以用eval转化为字典格式。
    # u=User('egon')                              #实例化u,名字为egon。
    # print(u.db['egon'])                         #实际就是eval(data)["egon"]--->{'age': 17, 'sex': 'mid', 'password': 520}
    # print(u.db['egon']['password'])             #再找key=“password"-->520。结束。
    ########################################################################################################################
    # 要求三:分析下述代码的执行流程
    # import time             #导入时间模块,以备后用。
    # class User:             #定义用户类。
    #     db_path='user.db'   #定义类的数据属性,这样所有User类实例化的对象,都可以用这个类的属性,统一归一设计。
    #     def __init__(self,name):  #定义类的内置函数,实例化中使用。
    #         self.name=name        #对象的数据属性只有一个,self.name。
    #     @property                 #增加property装饰器,为对象增加一个属性,其实这个属性是执行函数。
    #     def db(self):             #实际上是为对象定义db函数。
    #         with open(self.db_path,'r') as read_file:   #只读方式打开self.db_path,对象本身没有,只能到类中找,找到了"user.db"文件。
    #             info=read_file.read()    #info变量拿到文件所有内容。
    #             return eval(info)        #返回给self.db文件的所有内容,这是爱根的一个bug,只要print(self.db),就能拿到所有用户信息。
    #     @db.setter              #这是被property装饰的属性,在赋值或修改的时候使用。
    #     def db(self,value):     #其实是定义self对象的修改函数或新增函数,把value传进去。
    #         with open(self.db_path,'w') as write_file:      #以覆盖写的方式打开"user.db"文件。
    #             write_file.write(str(value))                #将新的值value写进去。以字符串的形式。
    #             write_file.flush()                          #然后立即刷新,即使刷新,避免时间差,但时间差还是有的,只不过很小罢了。
    #     def login(self):                #定义类的函数属性,即对象的绑定方法。
    #         data=self.db            #数据来源为self.db,其实就是拿到了property下db(self)函数的返回值evla(info),即字典格式的文件内容。
    #         if data[self.name]['status']:  #先找出该对象的key=登录名字,继而找出key="status"的登录状态,看是True还是False。
    #             print('已经登录')           #上面表示如果是True,则打印该内容。
    #             return True                #然后返回True,终结该函数。
    #         if data[self.name]['timeout'] < time.time():  #如果不是True的话判断该用户名下对应的时间是否小于当前时间,只有小于才有资格
    #             count=0                                   #继续往suite里面走,然后定义计数器。
    #             while count < 3:        #当count<3的时候,才会进行这个循环。
    #                 passwd=input('password>>: ')  #与用户交互,输入密码。
    #                 if not passwd:  #密码只有对与错,定义这个的意思是如果输入的是回车键"enter",那么将不会执行count+=1,会再让你输入。
    #                     continue    #直接跳出循环,从偷开始循环。
    #                 if passwd == data[self.name]['password']:  #如果密码正确的话,进入下个suite。
    #                     data[self.name]['status']=True    #修改登录状态,将False改为True。
    #                     data[self.name]['timeout']=0      #若以前被锁定过,因为登录成功了,所以将时间修改为0。
    #                     self.db=data      #调用@db.setter下的db函数,将修改过的data内容写进去。
    #                     break             #跳出该循环,因为登录成功了。
    #                 count+=1              #这个count+=1是输错密码的时候用的,因为正确的时候有break,所以可以放在这里。
    #             else:                     #当count=3的时候不执行以上while循环了,所以会执行这个else。我将他修改为这个形式。
    #                 data[self.name]['timeout']=time.time()+10   #else隐掉,下面两行往前缩进一个suite。一样的效果,
    #                 self.db=data    #都是在count=3的时候执行的,和上面的count+=1一个道理。就是将timeout增加10s。
    #         else:                           #当既没有登录,而且时间被滞后的情况下,执行该项。
    #             print('账号已经锁定10秒')     #告诉用户账户被锁定。
    #
    # u1=User('egon')
    # u1.login()
    # u2=User('alex')
    # u2.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)
        @property
        def lock_time(self):
            lock_time=self.db[self.name]["timeout"]-time.time()
            return lock_time
        @db.setter
        def db(self,value):
            with open(self.db_path,"w") as write_file:
                write_file.write(str(value))
                write_file.flush()
        def login(self):
                data=self.db
                if data[self.name]['status']:
                    print('已经登录')
                    return True
                if self.lock_time<=0:
                    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
                            print("你已经登录!")
                            break
                        count+=1
                    else:
                        data[self.name]['timeout']=time.time()+10
                        self.db=data
                else:
                    print('账号已经锁定10秒,还剩%s秒'%self.lock_time)
        def logout(self):
            data=self.db
            if data[self.name]["status"]:
                while True:
                    choice = input("Do you want to logout right now?Y/N")
                    if choice=="Y":
                        data[self.name]["status"]=False
                        self.db=data
                        break
                    if choice=="N":
                        exit()
                    if not choice:
                        continue
                    else:
                        print("Fuck you ,input Error!Sb!")
            elif not data[self.name]["status"]:
                if self.lock_time>0:
                    print("you have been locked and haven't login,you must wait %ss to login!"%self.lock_time)
                if self.lock_time<=0:
                    while True:
                        choice=input("you haven't login,do you want to login?Y/N")
                        if choice=="Y":
                            self.login()
                            break
                        if choice=="N":
                            exit()
                        if not choice:
                            continue
                        else:
                            print("Fuck you ,input Error!SB!")
    # u1=User('egon')
    # u1.login()
    # u1.logout()
    # u2=User('alex')
    # u2.login()
    # u2.logout()
  • 相关阅读:
    MyBatis学习之简单增删改查操作、MyBatis存储过程、MyBatis分页、MyBatis一对一、MyBatis一对多
    最简单的mybatis增删改查样例
    JAVA地址栏重写很详细
    rapid-generator JAVA代码生成器
    PouchDB:可随时同步的开源JavaScript数据库
    写给java web一年左右工作经验的人
    使用 XMLBeans 进行编程
    使用Spring JMS轻松实现异步消息传递
    Spring JMSTemplate 与 JMS 原生API比较
    浅析深究什么是中间件
  • 原文地址:https://www.cnblogs.com/chedanlangren/p/6750595.html
Copyright © 2020-2023  润新知