zoukankan      html  css  js  c++  java
  • Python【day 17-2】面向对象-成员

    ''''''
    '''
    1、简述面向对象三大特性并用示例解释说明?【背写】
        1、封装
            狭义的封装:把一组属性封装到一个对象,创建对象的时候
            广义的封装:代码块,函数、对象、类、模块-py文件都是封装
                       把封装后的对象看成一个黑盒子,只需要关注输入和输出,不必关注黑盒子内部的实现
        2、继承
            1、避免代码的重复
            2、可扩展
                共有的写在父类,扩展的时候用子类
        3、多态
    
    2. 面向中的变量分为哪几种?并用示例说明区别?【背写】
        1、成员变量
            写在构造方法中的,前面是self.  局部的意思
        2、类变量(静态变量)
            写在类中方法(成员方法)之外的变量,全局的意思
            多个对象共享的
    
    3. 面向对象中方法有哪几种?并用示例说明区别?【背写】
        1、成员方法
            1、包括构造方法和普通方法
            2、第一个参数是self
            3、通过对象来直接调用
        2、静态方法
            1、参数不需要self
            2、写法是方法名字上面加上一行@staticmethod
            3、通过类名来调用
            4、把它理解成类中的函数即可
        3、类方法
            1、参数只有一个cls,表示可以说传入类名
            2、写法是方法名字上面加上一行@classmethos
            3、通过类名来调用
            4、可以在类方法中创建对象,设计模式
    
    4. 面向对象中的属性有什么?并用示例说明?
       定义:用方法来表示一个属性(成员变量)
       写法:方法名字上面加一行@property
            只有一个参数self
            必须有返回值(属性取的就是返回值)
       调用:对象名.方法名
             注意方法名字后面不加小括号
       例子:人的年龄
            1、成员变量中,一般不存储人的年龄,因为年龄每年都会变
            2、成员变量中,存储的是人的生日
            3、可以用成员方法,根据生日计算年龄,但是年龄是一个属性-名称
               用方法-动词计算不是特别合适
            4、就引入了用方法的变种--属性来表示年龄
    
    5. 简述静态方法和类方法的区别?
        1、写法不同
            前者方法名字前面加上@staticmethod
            后者方法名字前面加上@classmethod
        2、参数不同
            前者的参数没有self
            后者的参数是cls
        3、含义不同
            前者可以理解成类中的函数,不需要传self,对象
            后者的参数传入的是类名,主要用于对象的创建,设计模式
    
    '''
    6. 面向对象的方法中那个无需传参数?
        静态方法无需传参数
        成员方法self
        类方法cls
    
    7. 面向对象中公有和私有成员,在编写和调用时有哪些不同?
        1、编写上
            后者名字前面需要加上__,前者不需要
        2、调用上
            后者不能通过对象直接访问
            后者可以通过对象调用公有成员方法的形式,访问私有变量或者私有方法
            (把私有变量或者私有方法写在公有成员方法中)
    
            前者可以通过对象直接访问
    # 18.现有50条数据.请使用面向对象的思维来完成这50条数据的分页工作(升级题)
    class Page:
        def __init__(self,lst,pagesize):
            self.lst = lst
            self.pagesize = pagesize
        def start(self):
            '''
            返回第一页的内容
            '''
        def end(self):
            '''
            返回最后一页的内容
            '''
        def index(self):
            '''
            返回指定页的内容
            '''
            page = input('请输入你要查询的数据的页数:')
    
    '''
    伪代码思路:
    第一步
    1、一共是6条数据,每页2条,分成3页
    2、输入页数1,打印1-2(索引号和值都是1,2)
    3、输入页数3,打印5-6
    
    第二步
    1、一共是5条数据,每页2条,分成3页
    2、输入页数1,打印1-2(索引号和值都是1,2)
    3、输入页数3,打印5
    
    '''
    
    class Page:
        def __init__(self,lst,pagesize):
            self.lst = lst
            self.pagesize = pagesize
        def start(self):
            '''
            返回第一页的内容
            '''
            # total_page = len(self.lst)/self.pagesize
            print(self.lst[:self.pagesize])
            return self.lst[:self.pagesize]
    
        def end(self):
            '''
            返回最后一页的内容
            '''
            total_page = len(self.lst) / self.pagesize
            # print(total_page)
            if type(total_page) == int:
                print(self.lst[-self.pagesize:])
                return self.lst[-self.pagesize:]
            else:
                result, remainder = divmod(len(self.lst),self.pagesize)
                # print(result)  2 商是2
                # print(remainder) 1 余数是1
                print(self.lst[-remainder:])  #[5]
                return self.lst[-remainder:]
    
        def specified_page(self,n):
            print(self.lst[self.pagesize*(n-1):self.pagesize*n])
            return self.lst[self.pagesize*(n-1):self.pagesize*n]
    
        def index(self):
            '''
            返回指定页的内容
            '''
            while 1:
                page = input('请输入你要查询的数据的页数,输入q退出:')
                if page.upper() == 'Q':
                    print('退出了')
                    break
                elif page == '1':
                    self.start()
                elif page == '-1':
                    self.end()
                elif page.isdigit() == False:
                    print('只能输入数字,请输入数字')
                elif int(page) <= (len(self.lst)/self.pagesize)+1 :
                    self.specified_page(int(page))
                # elif int(page) > (len(self.lst) / self.pagesize) + 1 :
                #     print('页码超出范围了')
                else:
                    print('页码超出范围了')
    
    # li1 = [1,2,3,4,5,6]
    li1 = [1,2,3,4,5]
    p1 = Page(li1,2)  #一共是5条记录,每页2条记录
    p1.index()
    print('------------------------18 ')
    ''''''
    '''
    19.在昨天最后一题的基础上.把数据写入到文件中.并且注册的时候需要到文件中判断是否重
    复.如果重复提示不能注册.(升级题
    '''
    
    # 16.    补充代码:实现用户注册和登录
    # class User:
    #     def __init__(self,user,pwd):
    #         self.user = user
    #         self.pwd = pwd
    
    class Account:
        def __init__(self):
            # user_list = []  #存放user对象  这个必须加上self变成成员变量才行
            # self.user_list = []  #存放user对象   #注意点2:这里必须加self,表示成员变量(可以在方法间使用)
    
            #新建文件
            # self.f1 = open('acount.txt',mode='w+',encoding='utf-8')  #先w+  后a+  可写可读 每次都清空,覆盖
            self.f1 = open('acount.txt',mode='a+',encoding='utf-8')  #先w+  后a+   可追加可读
            #1 新建文件,文件对象存储成成员变量,方便方法间使用
    
        def register(self): #1 注册功能
            print('欢迎来到注册页面')
            username = input('请输入你要注册的登录用户名:')
            password = input('请输入你要注册的登录密码:')
            # u1 = User(username,password)  #新建对象,对象中封装正确的用户名和密码
            # self.user_list.append(u1)  #self.user_list 表示成员变量(可以在方法间使用)
            # print(self.user_list) #[<__main__.User object at 0x00000098C5EDF0C8>]
    
            #一、先判断用户名是否在文件中已经存在
            self.f1.seek(0, 0)  # 1光标到文件开头   关键点1
            #是在第二次运行程序的时候,判断用户名是否存在的时候,从历史注册用户名中进行查找、判断、去重
            for i in self.f1:  # 2 遍历文件对象,读取文件中每一行
                if username == i.split('|')[0]:#3 判断用户输入的用户名和文件中已经存在的用户名进行比对
                    print('用户名已经存在')
                    break  #4,如果已经存在,就跳出整个for循环
            else: #5 如果没有任何break 正常结束,执行else,如果有break,else下面就不会执行
            # 如果不写else,即使有break,下面的内容也会执行; 有没有else,在break的情况下,执行是完全不同的
                #6 往空白文件中写入用户名和密码
                self.f1.write(username+'|'+password+'
    ')
                self.f1.flush()  #7 将写入的及时刷新到文件
                # self.f1.seek(0,0)  #光标到文件开头
                # self.f1.close()  #8 先不关闭,如果在这里关闭,就会报错
                #ValueError: I/O operation on closed file.
    
        def login(self): #2 登录接口
            print('欢迎来到登录页面')
            n = 0
            for i in range(3):  #3次重试机会
                username2 = input('请输入你要登录的登录用户名:')
                password2 = input('请输入你要登录的登录密码:')
                # for i in self.user_list:   #循环遍历用户对象  self.user_list表示成员变量(可以在方法间使用)
                self.f1.seek(0, 0)  # 1、光标到文件开头  关键点2
                #2 在用户输入用户名和密码登录的时候,需要从文件开头遍历已经注册的用户名和密码
                for i in self.f1:   #3 循环遍历文件对象  self.f1表示成员变量(可以在方法间使用)
                    # if i.user == username2 and i.pwd == password2:  #关键点1 i.user取的是对象的属性
                    if i.split('|')[0].strip() == username2 and i.split('|')[1].strip() == password2:  #
                        #4 strip()是为了去掉换行符
                        #5 把用户输入的用户名密码和文件中的用户名密码进行匹配
                        print('登录成功')
                        # self.f1.close()  #关闭文件  检查点
                        #ValueError: I/O operation on closed file.
                        # break  #注意点3  只能退出当层内循环
                        return  #注意点4  可以退出内层循环和外层循环(一次退出2层循环)
                else:  #6 这个else必须是和for同级,而不能是和if同级  关键点2
                    #因为期望结果的每行判断完,才能说明登录失败
                    n+=1
                    print('登录失败,请重新输入,你还有 %s 次重试机会' % (3-n) )
            self.f1.close()  # 7关闭文件 注意这行代码的位置  关键点3
    
        def run(self):#3 选择注册还是登录,先注册,后登录
            while 1:
                choice = input('请选择,1表示注册,2表示登录,Q表示退出:')
                if choice == '1':
                    self.register()  #注意点1  方法前面必须加上self
                elif choice == '2':
                    self.login()  #注意点1  方法前面必须加上self
                elif choice.upper() == 'Q':
                    print('已经退出了')
                    break
                else:
                    print('你输入的不对,请重新输入')
    
    a1 = Account()
    a1.run()
    '''
    注册和登录的逻辑:
    1、注册的时候,把正确的用户名和密码,比如:jack/123 存入数据库(或者对象中,列表中)
       保存之前,先判断用户名在文件中是否已经存在,如果重复提示不能注册
    2、登录的时候,输入登录用户名和密码,拿用户输入的用户名和密码 和之前注册的用户名和密码进行比对
       如果相等匹配,就是登录成功
       如果不相等不匹配,就是登录失败
    3、之前是将注册后的用户名和密码存在列表中--内存中
       现在需要存在文件中(类似于-持久化到数据库)
    
    注意点:
    1、光标的位置回到文件的开头
    2、关闭文件对象的代码所在的位置
    
    扩展:
    1、能否把对象写入文件中--不能
       --文件中只能写入字符串,不能写入对象
    2、先实现用户名|密码+换行符 写入文件
    3、注册用户名去重--ok
    
    接口的概念:
    1、接口可以对外提供服务,对外提供功能,接口是服务端
    2、客户端-发起端发起请求,调用登录接口
        只需要传入正确的参数(用户名和密码),就可以登录成功
    '''
  • 相关阅读:
    CocosCreator-Widget,前后台切换
    Unity获取未激活游戏对象的方法 、坐标转换
    Mathf函数
    C# activeSelf、activeInHierarchy、SetActive、SetActiveRecursively
    C# 碰撞,射线,点击,周期函数等基本代码
    TCP/IP 协议栈
    笔记—《程序员自我修养》
    Container With Most Water 双指针法
    多线程服务器 编程模型
    c++ 高效并发编程
  • 原文地址:https://www.cnblogs.com/wangtp/p/12020172.html
Copyright © 2011-2022 走看看