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+'\n') 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、客户端-发起端发起请求,调用登录接口 只需要传入正确的参数(用户名和密码),就可以登录成功 '''