python面型对象编程进阶(继承、多态、私有化、异常捕获、类属性和类方法)(上):https://developer.aliyun.com/article/1483375
7.property方法
属性函数
class A(object): def __init__(self): self.__name = 18 def __eat(self): return self.__name pass pass def run(self): print('跑步') pass pass age = property(__eat, run) b = A() print(b.age) ## 报错 b.run() ## 跑步
7.1 @age.setter ##修改属性
class A(object): def __init__(self): self.__name = 18 def __eat(self): return self.__name pass pass def run(self): print('跑步') pass @property ##添加属性标识 def age(self): return self.__name pass @age.setter ##修改属性 def age(self,params): self.age = params pass pass p1 = A() print(p1.age) ## 18 p1.age = 16 print(p1.age)
8. new方法
作用:创建并返回一个实例对象,如果new只调用了一次,就会得到一个对象。继承自object的新式类,才有new这一魔术方法。
8.1 注意事项
1.__new__是一个实例化调用的第一个方法 2.__new__至少必须有一个参数 cls,代表要实例化的类,此参数在实例化时由python解释器提供,其他的参数是直接传递给__init__方法 3.__new__决定是否使用该__init__方法,因为__new__可以调用其他的类的构造方法或者返回实例对象作为类的实例,如果__new__没有返回实例,则__init__不会被调用 4.在__init__方法中,不能调用自己的__new__方法,return cls__new__(cls),否则会报错。
class A(object): def __init__(self): print('__init__执行了') pass pass def __new__(cls,*args,**kwargs): return super().__new__(cls,*args,**kwargs) pass pass a = A() print(a) __init__执行了 <__main__.A object at 0x00000291F97D5160> ## 当__new__返回的时候 __init__才会显示
9.单例模式
9.1 确保一个类只有一个实例存在,使用new
class DataBaseClass(object): def __new__(cls,*args,**kwargs): ## cls._instance = cls.__new__(cls) ##不能使用自己的new方法 if not hasattr(cls,'_instance'): cls._instance = super().__new__(cls,*args,**kwargs) return cls._instance pass pass db1 = DataBaseClass() db2 = DataBaseClass() db3 = DataBaseClass() print(id(db1)) print(id(db2)) print(id(db3)) ## 三个指向的内存地址都一样的 ## 1852298514784 ## 1852298514784 ## 1852298514784
10 错误和异常处理
try: ## 可能出现错误的代码块 except: ## 出错之后执行的代码块 else: ## 没有出错的代码块 finally: ## 不管有没有出错,都会执行
10.1 错误和异常处理示例
try: ## 可能出现错误的代码块 li = [1,2,3] ## print(li[10]) print(1/0) except IndexError as msg: ## 出错之后执行的代码块 print(msg) except ZeroDivisionError as msg: ## 出错之后执行的代码块 print(msg) else: ## 没有出错的代码块 print('没有出错了') finally: ## 不管有没有出错,都会执行 print('出错了') ## 用一个try可以捕获多个不同类型的异常
10.2 使用 Exception处理所有错误
try: print(b) except Exception as result: print(result) else: print('出错了') finally: print('出错了')
10.3在合适的层次去捕获
def A(s): return s/int(s) pass def B(s): return A(s)/2 pass def main(): try: B(0) except Exception as result: print(result) main()
在合适的位置进行错误捕获
division by zero
10.4 异常运行机制
1、解释器会查找相应的异常捕获类型 2、不断传递给上层,没有找到异常处理,会退出
11.自定义异常类型
class ToolongException(Exception): def __init__(self, len): self.len = len def __str__(self): return '输入的长度是'+str(self.len)+'长度,超出长度了' def name_test(): name = input('输入名字') try: if len(name)>5: raise ToolongException(len(name)) else: print(name) except ToolongException as result: print(result) else: print('没有出错了') name_test() ##输入的长度是13长度,超出长度了
12 动态添加属性和方法
import types class Student: def __init__(self, name, age): self.name = name self.age = age pass pass def __str__(self): return '{}今天{}岁了'.format(self.name, self.age) pass pass zhz = Student('詹躲躲', 25) zhz.wight = 60 def dymicMethod(self): print('{}体重是{}'.format(self.name,self.wight)) pass ## 动态添加属性 print(zhz.wight) ## 类添加属性 Student.pro = '计算机科学' ## 实例可以访问 print(zhz.pro) ## 动态添加实例方法 ## import types zhz.printInfo = types.MethodType(dymicMethod,zhz) zhz.printInfo() ## 詹躲躲体重是60
13 动态绑定类方法
import types class Student: def __init__(self, name, age): self.name = name self.age = age pass pass def __str__(self): return '{}今天{}岁了'.format(self.name, self.age) pass pass zhz = Student('詹躲躲', 25) zhz.wight = 60 def dymicMethod(self): print('{}体重是{}'.format(self.name,self.wight)) pass ## 动态绑定类方法 @classmethod def classTest(cls): print('类方法') pass ## 动态绑定静态方法 @staticmethod def staticTest(): print('静态方法') pass
13.1.动态添加属性
print(zhz.wight)
13.2.类添加属性
Student.pro = '计算机科学' ## 实例可以访问 print(zhz.pro)
13.3.动态添加实例方法
## import types zhz.printInfo = types.MethodType(dymicMethod,zhz) zhz.printInfo()
13.4.动态绑定类方法
Student.testMethod = classTest Student.testMethod()
13.5.动态绑定类方法 实例调用
zhz.testMethod()
13.6.动态绑定静态方法
Student.statictest = staticTest Student.statictest()
13.7.动态绑定静态方法 实例调用
zhz.statictest()
14.slots属性
class Student(object): __slots__ = ('name', 'age', 'score') def __str__(self): return "{},{}".format(self.name, self.age) xw = Student() xw.name = '叫我詹躲躲' xw.age = 25 ## print(xw.__dict__) ## {'name': '叫我詹躲躲', 'age': 25} xw.s11 = '1212' #### 报错 print(xw)
子类未声明 slots,不会继承父类的slots,此时子类可以随意的属性赋值
子类声明了,范围为 子类+父类的范围
15.题目练习 一
15.1 python new的方法和作用是什么?
用来创建实例对象,只有继承了object的话,才有这个方法。
15.2 什么是单例模式,适用于什么场景?
要求一个类有且只有一个实例,并且提供了全局的访问点。日志插入logger,网站计数器,权限验证模块,window资源管理器,系统回收站,数据库连接池
15.3 私有化方法和私有化属性在子类中能否继承?
不能的
15.4 在python中什么是异常?
程序在执行中出现的异常。
15.5 python中如何处理异常?
分别根据异常的类型去处理
15.6 python中异常处理的一般格式,可以使用伪代码描述?
## try: ## 正常操作 ## except: ## ##.... ## else: ## ##.... ## finally: ## ##...
15.7 slots的作用
限制属性的随意输入,节省内存空间
15.8 私有化的属性的作用?
保护数据,封装性的体现
15.9 在类外是否修改私有属性?
不可以直接修改,通过方法去实现,可以借助property
15.10 如果一个类,只有指定的属性或者方法能被外部修改,该如何限制?
对属性进行私有化
16 题目练习二
16.1 定义一个person类,类中要有初始化方法,方法中要有人名,年龄两个私有属性
提供获取用户信息的函数,提供设置私有属性的方法,设置年龄在0-120岁中间,如果不在这个范围,不能设置成功
class Person: def __init__(self,name,age): self.__name = name self.__age = age pass pass def GetUserInfo(self): return "{}的年龄为{}".format(self.__name,self.__age) pass pass def __str__(self): return "{}的年龄为{}".format(self.__name,self.__age) def setAge(self,age): if age>0 and age<120: self.__age = age else: pass person = Person('詹躲躲',19) print(person.GetUserInfo()) ## 詹躲躲的年龄为19 print(person.setAge(30)) print(person.GetUserInfo()) ## 詹躲躲的年龄为30
16.2 请写一个单例模式
class DataBaseClass(object): def __new__(cls,*args,**kwargs): ## cls._instance = cls.__new__(cls) ##不能使用自己的new方法 if not hasattr(cls,'_instance'): cls._instance = super().__new__(cls,*args,**kwargs) return cls._instance pass pass db1 = DataBaseClass() db2 = DataBaseClass() db3 = DataBaseClass() print(id(db1)) print(id(db2)) print(id(db3))
16.3 创建一个类,并定义两个私有化属性,提供一个获取属性的方法。利用property属性给调用者提供调用
class Student: def __init__(self, name, score): self.__name = name self.___score = score @property def name(self): return self.__name @name.setter def name(self, name): self.__name = name def __str__(self): return self def __call__(self, *args, **kwargs): print(self.name) pass pass xm = Student('詹躲躲',98) xm.__call__() xm.name()
16.4 创建一个Animal类。实例一个cat对象,给cat 绑定一个run方法,给类绑定一个类属性color
import types class Animal: pass def run(self): print('小猫') cat = Animal() cat.run = types.MethodType(run,cat) cat.run() Animal.color = 'red' print(cat.color) def info(): print('ok') Animal.info = info Animal.info()