语法错误和异常 异常:程序运行的时候报出来的,xxxError 异常处理格式: try: 可能出现异常的代码 except: 如果有异常执行的代码 finally: 无论是否存在异常都会被执行的代码 情况一: try: 有可能产生多个异常 except 异常类型1: print() except 异常类型2: print() 注意:如果是多个except,异常类型的顺序许哟啊注意,最大的Exception要放在后面 情况二:获取Exception的错误原因 except Exception as err: print('Error',err)------》就是错误原因 [Error pop from empty list] def func(): try: a=int(input('请输入一个数字:')) b=int(input('请输入一个数字:')) f=input('请输入一个符号(+ - * /):') if f=='+': result=a+b elif f=='-': result=a-b elif f=='*': result=a*b elif f=='/': result=a/b else: print('输入的符号不正确') print(result) list=[] list.pop() with open(r'F:\mm','r')as rstream: container=rstream.read() print(container) except ZeroDivisionError: print('除数不可以为0') except ValueError: print('请输入数字') except Exception as err: print('Error',err) func() 情况三: try: 有可能有异常的代码 except 类型1: pass else: 如果try中没有异常则进入的代码 注意:如果使用else则在try代码中不能出现return 情况四: 文件操作:fp=open() fp.read() fp.close() 数据库操作:close() try: pass except: pass finally: 无论是否异常都需要执行的代码 def func(): rstream=None try: with open('book', encoding='utf-8')as rstream: print(rstream.read()) return 1 # rstream = open(r'F:\p\ww\book.txt', 'rb', encoding='UTF-8') except Exception as err: print(err) return 2 finally: print('enter---------') if rstream: rstream.close() return 3 x=func() print(x) ''' 抛出异常 raise 注册: 用户名必须是6位 ''' def register(): username=input('输入用户名:') if len(username)<6 or len(username)>6: raise Exception('用户长度必须是6位') else: print('您的用户名是:{}'.format(username)) try: register() except Exception as err: print(err) else: print('chenggong ') 集合推导式: 与列表推导式相似 只是符号不同,在列表推导式的基础上添加了一个去除重复项的功能,用{}表示 llist=[1,2,3,4,1,34] set={x for x in llist} print(set) ''' 字典推导式(不是重点 了解即可) 用字典推导式 实现键值交换 ''' dict={'a':'S','b':'B','c':'C','c':'D'} new_dict={value:key for key,value in dict.items()} print(new_dict) # {'S': 'a', 'B': 'b', 'D': 'c'} ''' 通过列表生成式(列表推导式),我们可以直接创建一个列表。 但是,受到内存限制,列表容量肯定是有限的 而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间 如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了 所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢 这样就不必创建完整的list,从而节省大量的空间。在python中,这种一边循环一边计算的机制,称为生成器 ''' ''' 得到生成器的方式: 1、通过列表推导式得到生成器 符号是() ''' g=(i*3 for i in range(10)) print(type(g)) # 通过调用__next__()方式得到元素 print(g.__next__()) print(g.__next__()) # <class 'generator'> # 0 # 3 ''' 2、系统方法: next() 每调用一次next则会产生一个元素 ''' g=(i*3 for i in range(10)) print(type(g)) print(next(g)) # <class 'generator'> # 0 ''' StopIteration 生成器本来就只可以产生10个 但是代码仍然要求接着产生 这时会报错 ''' 定义生成器的方式二:借助函数完成 只要函数中出现了yield关键字,说明函数就不在是函数了,而变成了生成器了 步骤: 1、定义一个函数,并在函数中使用yield关键字 2、调用函数,接收调用的结果 3、得到的结果就是生成器 4、借助于next() ,next ()得到元素 next()相当于return 和break ''' def func(): n=0 while True: n+=1 yield n g=func() print(type(g)) print(next(g)) print(next(g)) # <class 'generator'> # 1 # 2 # 用生成器实现斐波那契数列 def fib(lenght): a,b=0,1 while True: n=0 if n<lenght: c=a+b a,b=b,a+b n=n+1 yield c g=fib(100) 生成器方法: __next__():获取下一个元素 sendvalue():向每次生成器调用中传值 注意:第一次调用send(None) def gen(): i=0 while i<5: temp=yield i print(temp) i+=1 return '没有更多的数据' g=gen() print(g.send(None)) n1=g.send('呵呵') print(n1) ''' 进程——》线程——》协程 ''' def task1(n): for i in range(n): print('正在搬第{}块砖'.format(i)) yield def task2(n): for i in range(n): print('正在听{}首歌'.format(i)) yield g1=task1(12) g2=task2(3) while True: try: g1.__next__() g2.__next__() except StopIteration: print('wrong') break ''' 可迭代对象:1、生成器 2、元组 列表 集合 字典 字符串 用isinstance进行判断 迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象 迭代器对象从集合的第一个元素开始访问,直到所有的元素都被访问完结束 迭代器只能往前不会后退 可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator 可迭代的是不是肯定就是迭代器? 生成器是可迭代的,也是迭代器 list是可迭代的,但是不是迭代器——》变成迭代iter(iteration) 生成器和迭代器的关系: 生成器只是迭代器的一种 ''' from collections.abc import Iterable list=[1,2,3,4,5,6] if isinstance(list,Iterable): print('true') else: print('false') print('__________') g=(x+1 for x in range(2)) if isinstance(g,Iterable): print('true') else: print('false') print('_______') list=[1,2,3,4] list1=iter(list) print(next(list1)) print(next(list1)) ''' 面向对象: 程序 现实中 对象: 具体的事物 类 对象 属性 方法 所有的类名要求首字母大写,多个单词使用驼峰式命名 class 类名(父类): 属性 特征 方法 动作 ''' ''' 定义类和属性 ''' class Student: # 类属性 name='hua' age=2 ''' 使用类,创建对象 ''' xiaowei=Student() xiaowei.age=12 Student.name='ruirui' print(Student.name) # 对象属性 # 对象对属性的寻找 先在自己空间找 没有后再去类中找 ''' 类中的方法 种类:普通方法 类方法 静态方法 魔术方法 ''' ''' 普通方法的格式: def 方法名(self,参数): pass ''' class Phone: brand='xiaomi' price=3000 type='note 8 pro' # phone类内部方法:call def call(self): print(self) for list in self.phone_list: print(list.items()) print('正在打电话') print(self.note) phone1=Phone() phone1.note='我是phone1的note' phone1.phone_list=[{'num1':'1234'},{'num2':'8907'}] # print(phone1,'----------') # print(phone1.brand) phone1.call() print('*'*20) phone2=Phone() phone2.note='我是phone2的note' # print(phone2) phone2.call() ''' class Phone: # 魔术方法之一:__名字__() def call(self): # self是不断变化的 print(self.price) # 不能保证每个self中都存在price print('----call') p=Phone() p.price=90 p.call() ''' class Iphone: def __init__(self): print('--------init') def call(self): print('---------call') i=Iphone() ''' 1、找有没有一块空间是Iphone 2、利用Iphone类,向内存申请一块'Phone'一样的空间 3、去IPhone中找有没有__init__,如果没有则直接将内存地址赋值给对象名 4、如果有__init__,则会进入init方法执行里面的动作,执行结束胡,将内存地址赋值给对象 ''' print('--------------------------------------') class Person: name='张三' def __init__(self): self.name='张三' self.age=10 def eat(self): print('{}正在吃饭'.format(self.name)) def run(self): print('{},今年{}岁,正在跑步'.format(self.name,self.age)) p=Person() p.name='梨子' p.eat() p1=Person() p1.name='西红柿' p1.run() print('*'*20) class Qperson: name='张三' def __init__(self,name,age): self.name=name self.age=age def eat(self,name): print('{}正在吃饭'.format(self.name)) def run(self,name,age): print('{},今年{}岁,正在跑步'.format(self.name,self.age)) p=Qperson('lili',89) p.eat('bing') ''' 类方法 特点: 1、定义需要以来装饰器@classmethod 2、类方法中的参数不是一个对象,而是一个类 3、类方法中只可以使用类属性 4、类方法只可以使用类属性 5、类方法中可否使用普通方法? 不能 类中方法的调用,需要通过self.方法名()调用 ''' ''' 类方法作用: 因为只能访问类属性和类方法,所以可以在对象创建之前,如果需要完成一些动作 不依赖于对象 ''' class Dog: def __init__(self,nickname): self.nickname=nickname # 动态添加属性 def run(self): # self 对象 print('{}在院子里跑来跑去'.format(self.nickname)) @classmethod def test(cls): # cls class print(cls) print(cls.nickname) d=Dog('nick') print(d.nickname) d.run() d.test() print('------------------------------------------------') ''' _属性名:表示这是一个私有属性 不可以通过类或者对象直接进行修改 ''' class Person: _age=18 def show(self): print('--------',self.age) @classmethod def update_age(cls): cls._age=20 print('-------类方法') @classmethod def show_age(cls): print(cls._age) Person.update_age() Person.show_age() # Person.age=Person.age+1 # print(Person.age) print('-------------------------------------------') ''' 静态方法:类似类方法 1、需要装饰器@staticmethod 2、静态方法无需传递self、cls参数 3、只能访问类的属性和方法,对象的属性和方法无法使用 4、加载实际同类方法 总结: 类方法 静态方法 不同: 1、装饰器不同 2、类方法是有参数的,静态方法没有参数 相同: 1、只能访问类的属性和方法,对象的属性和方法是无法访问的 2、都可以通过类名调用访问 3、都可以在创建对象之前使用,因为是不依赖于对象 普通方法与二者的区别与联系: 不同: 1、没有装饰器 2、普通方法永远是要依赖对象,因为每个普通方法都有一个self 3、只有创建了对象才可以调用普通方法,否则无法使用 ''' class Iperson: _age=18 def show(self): print('--------',self.age) @classmethod def update_age(cls): cls._age=20 print('-------类方法') @classmethod def show_age(cls): print(cls._age) @staticmethod def test(): print('----------静态方法') print(Iperson._age) Iperson.update_age() Iperson.test() ''' 魔术方法: 1、__init__ 初始化魔术方法 触发时机:初始化对象时触发(不是实例化触发,但是和实例化在一个操作中) 参数:至少有一个self,接收对象 返回值:无 作用:初始化对象的成员 注意:使用该方式初始化的成员都是直接写入对象中,类中无法具有 2、__new__ 实例化魔术方法:给对象开辟地址空间 触发时机:在实例化时触发 参数:至少一个cls接收当前类 返回值:必须返回一个对象实例 作用:实例化对象 注意:实例化对象时Object类底层实现,其他类继承了Object的_new_才能实现实例化对象 没事别碰这个魔术方法:先触发__new__才会触发__init__ object.__new__(cls) 3、__call__ 调用对象的魔术方法 触发时机:将对象当作函数调用时触发 对象() 参数:至少一个self接收对象,其余根据调用时参数决定 返回值:根据情况而定 作用:可以将复杂的步骤进行合并操作,较少调用的步骤,方便使用 注意:无 如果想让对象当作函数进行使用,需要重写__call__()方法 4、__del__ 1.对象赋值: p=Person() p1=p 说明p p1都指向同一个地址空间 2.删除地址的引用: del p1 删除p1对地址的引用 3.查看对地址的引用次数: import sys sys.getrefcount(p) 4.当一个空间没有了任何引用,默认执行__del__ ref=0 ''' class Person: def __init__(self): print('----------------init') print(self) def __new__(cls, *args, **kwargs): # 向内存要空间 print('-----------------new') # return object.__new__(cls,*args,**kwargs) result= object.__new__(cls, *args, **kwargs) # position=object.__new__(cls) print(result) return result def __call__(self, name): print('--------------------call') print('名字是',name) p1=Person() p1('nick') # Person.__new__() # -----------------new # <__main__.Person object at 0x0000027BC9BBE1F0> # ----------------init # <__main__.Person object at 0x0000027BC9BBE1F0> print('----------------') import sys class Iperson: def __init__(self,name): self.name=name def __del__(self): print('---------del----------') ip=Iperson('hello') ip1=ip ip2=ip print(ip1.name) print(ip2.name) print(sys.getrefcount(ip)) # getrefcount()获取指向该地址的指针个数 del ip1 # ip1.name='keleld' # print(ip.name) # print(ip2.name) print(sys.getrefcount(ip)) n=3 n1=n print(n1) ''' __str__ 触发时机:打印对象名,自动触发去调用__str__里面的内容 注意:一定要在__str__方法中添加return,return后面内容就是打印对象看到的内容 魔术方法就是一个类/对象中的方法,和普通方法唯一的不同是,普通方法需要调用,而魔术方法是在特定时刻自动爆发 ''' class Person: def __init__(self,name,age): self.name=name self.age=age def __str__(self): return '姓名是'+self.name+',年龄是:'+str(self.age) p=Person('tom',12) print(p) # 单纯打印对象名称,出来的是一个地址,地址对于开发者来说没有太大意义 # 如果想在打印对象名的时候能够给开发者更过一些信息量 p1=Person('Jack',20) print(p1) ''' 总结:魔术方法 重点: __init__ 创建完空间后指行的第一个方法 __str__ 了解: __new__ 开辟空间 __del__ 没有指针引用的时候会调用 __call__ 想不想将对象当成函数用 class Student: def __init__(self,name,age): self.__name=name self.__age=age self.__score=59 def setAge(self,age): # set是为了赋值 if age>0 and age<120: self.__age=age else: print('beyond') def setName(self,name): if len(name)>6: print('名字长度超出范围') else: self.__name=name def getAge(self): return self.__age def __str__(self): return '姓名{},年龄{},你的分数是:{}'.format(self.__name,self.__age,self.__score) s=Student('lily',12) print(s) print('--------') print(s.getAge()) s.setAge(1223) print(s) s.setName('xiaopeng') print(s) print('------------------------------') print(dir(Student)) print(dir(s)) print('==================') print(s._Student__age) # # s.__score=90 # 私有化: # 封装:1、私有化属性 2、定义公有set和get方法 # 好处: # 1、隐藏属性不被外界随意修改 # 2、也可以修改,通过函数 # def setXXX(self,xxx) # 筛选赋值的内容 #3、如果想获取具体的某一个属性: # 使用get函数 # 私有属性 系统会自动改名字 所以不可以直接访问 if age<100 and age>0: self.__age=age else: print('不在规定的范围内') ''' 继承 is a has a ''' ''' 两个类: 公路(Road) 属性:公路名称 公路长度 车(Car) 属性:车名 时速 方法:1、求车名在那条公路上以多少的时速行驶了多长 get_time(self,road) 2、初始化车属性信息__init__方法 3、打印对象显示车的属性信息 ''' import random class Road: def __init__(self,name,length): self.name=name self.length=length class Car: def __init__(self,name,speed): self.name=name self.speed=speed def get_time(self,road): ran_time=random.randint(1,10) print('{}在{}公路上行驶速度为每小时{}'.format(self.name,road.name,self.speed)) def show(self): print('车的名称{},车的时速{}'.format(self.name,self.speed)) c=Car('奔驰','60') c.show() print('--------------') r=Road('五三街道','100') c.get_time(r) class Computer: def __init__(self,brand,type,color): self.brand=brand self.type=type self.color=color def online(self): print('正在使用电脑上网') def __str__(self): return self.brand+'-----'+self.type+'-------'+self.color class Book: def __init__(self,bname,author,number): self.bname=bname self.author=author self.number=number def __str__(self): return self.bname+'---'+self.author+'------'+self.number class Student: def __init__(self,name,computer,book): self.name=name self.computer=computer self.books=[] self.books.append(book) def borrow_book(self, book): for book1 in self.books: if book1.bname==book.bname: print('已经借过了') break else: self.books.append(book) print('{}已经添加成功'.format(book.bname)) def show_book(self): for book in self.books: print(book.bname) def __str__(self): return self.name+'---'+str(self.computer)+'------'+str(self.books) c=Computer('mac pro','mac 2018','深灰色') book=Book('盗墓笔记','南派三叔',10) s=Student('songsong',c,book) print(s) book1=Book('西游记','吴承恩',8) print(s.show_book()) s.borrow_book(book1) print('----------') s.show_book() # 知识点: # 1、has a # 一个类中使用了另外一种自定义的类型 # 2、类型 # 系统类型:str、int、float、list、dict、tuple、set # 自定义类型:算式自定义的类,都可以将其当成一种类型 # s=Student() # s是Student类型的变量 # is a # 继承: Student Employee Doctor——都属于人类 # 相同的代码——》代码冗余 ,可读性不高 # 将相同的代码进行提取——》Person类 # Student,Employee,Doctor——》继承Person ''' 特点: 1、如果类中不定义__init__,调用super class 的__init__ 2、如果类继承父类也需要定义自己的__init__,就需要在当前类的__init__调用一下父类__init__ 3、如何调用父类__init__ super().__init__(参数): super(类名,对象).__init__(参数): 4、如果父类有eat()方法,子类也定义一个eat方法,默认搜索的原则:先找当前类,再去找父类 s.eat() override:重写(覆盖) 父类提供的方法不能满足子类的需求,就需要在子类中定义一个同名的方法 5、子类的方法中也可以调用父类的方法: super().方法名(参数) ''' class Person: def __init__(self,name,age): self.name=name self.age=age def eat(self): print(self.name+'正在吃饭....') def run(self): print(self.name+'正在跑步。。。。。') class Student(Person): def __init__(self,name,age,clazz): print('------------Student init') super().__init__(name,age) self.clazz=clazz def study(self,course): print('{}正在学{}课程'.format(self.name,course)) def eat(self,food): super().eat() print(self.name + '正在吃饭....,喜欢吃{}'.format(food)) # 调用父类的方法 class Employee(Person): def __init__(self,name,age,salary,born): super().__init__(name,age) self.salary=salary self.born=born class Doctor(Person): def __init__(self,name,age,patient): super().__init__(name, age) self.patients=[] self.patients.append(patient) def show(self): for patient in self.patients: print(patient) s=Student('jack',18,'一班') e=Employee('tom',23,10000,11) s.study('python') s.eat() print('-------------') d=Doctor('lucy',20,'lumingming') d.run() d=Doctor('lucy',20,'lily') d.show() ''' 编写一个简单的工资管理程序,系统可以管理以下四类人:工人(worker)、销售员(salesman)、经理(manager) 、销售经理(salesman) 所有的员工都具有员工号、姓名、工资等属性,有设置姓名、获取姓名、获取员工号,计算工资等方法。 1)工人:工人具有工作小时数和时薪的属性,工资计算方法为工作小时数*时薪 2)销售员:具有销售额和提成比例的属性,工资计算方法为销售额+提成比例 3)经理:具有固定月薪的属性,工资计算方法为固定月薪 4)销售经理:工资计算方法为销售额*提成比例+固定月薪 请根据以上要求设计合理的类,完成以下功能: 1)添加所有类型的人员 2)计算月薪 3)显示所有人工资情况 ''' class Person: def __init__(self,number,name,salary): self.number=number self.name=name self.salary=salary def setName(self,name): self.name=name return self.name def getName(self): return self.name def getNumber(self): return self.salary def getSalary(self): return self.salary def __str__(self): return '员工号:{},薪水:{},姓名:{}'.format(self.number,self.salary,self.name) class Worker(Person): def __init__(self,number,name,salary,hour,per_hour): super().__init__(number,name,salary) self.hour=hour self.per_hour=per_hour def getSalary(self): money=self.hour*self.per_hour self.salary=self.salary+money return self.salary class Salesman(Person): def __init__(self,number,name,salary,salemoney,percent): super().__init__(number,name,salary) self.salemoney=salemoney self.percent=percent def getSalary(self): money=self.percent*self.salemoney self.salary=self.salary+money return self.salary w=Worker('001','king',2000,160,100) print(w.getSalary()) print(w) print('-----------') s=Salesman('002','lucy',5000,50000,0.003) print(s.getSalary()) print(s)
python——面向对象
最新推荐文章于 2024-11-11 21:30:41 发布