python面型对象编程进阶(继承、多态、私有化、异常捕获、类属性和类方法)

原创:叫我詹躲躲
来源:掘金
连接:python面型对象编程进阶(继承、多态、私有化、异常捕获、类属性和类方法)
致谢:感谢求知教育提供的视频教程python

1.单继承

## 封装,继承和多态
## 1.封装 1、知足把内容封装到某个地方,另外一个地方去调用封装的内容 2、使用初始化构造方法,或者使用self获取封装的内容  ## 2.继承 子类继承父类的属性和内容 复制代码

1.1单继承示例

class Animal:
 def eat(self):  print('吃饭了')  pass   def drink(self):  print('喝水了')  pass   class Dog(Animal):  def wwj(self):  ## 子类独有的实现  print('小狗汪汪叫')  pass  class Cat(Animal):  def mmj(self):  ## 子类独有的实现  print('小猫喵喵叫')  pass  d1 = Dog() d1.eat()  d2 = Cat() d2.eat()  ## 总结:因此对于面向对象的继承来讲,能够极大的提高效率,减小重复代码 复制代码

2.多继承

class Shenxian:
 def fly(self):  print('神仙会飞')  pass  class Monkey:  def chitao(self):  print('猴子喜欢吃桃')  pass  class Sunwukong(Shenxian,Monkey):  pass  swk = Sunwukong() swk.fly() swk.chitao()  复制代码

2.1 注意方法重名:

## 多个父类存在相同的方法,该调用哪个
class D(object):  def eat(self):  print('D.eat')  pass  class C(object):  def eat(self):  print('C.eat')  pass   class B(D):  pass  class A(B,C):  pass  a = A() a.eat print(A.__mro__) ##显示类的继承顺序 <class '__main__.A'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.C'>, <class 'object'> ## 执行顺序应该是 去A里面查找,找第一个父类,A中没有的话,去B中查找,,B类中没有,C类中没有,去D类中查找; 复制代码

2.2案例 简洁继承

class Grandfather():
 def eat(self):  print('吃的方法')  pass  pass  class Father(Grandfather):  pass  class Son(Father):  pass  son = Son() print(Son.__mro__)  ## <class '__main__.Son'>, ## <class '__main__.Father'>, ## <class '__main__.Grandfather'>, ## <class 'object'>  复制代码

2.3重写父类方法

class Grandfather():
 def eat(self):  print('吃的方法')  pass  pass  class Father(Grandfather):  ## 覆盖了父类的方法  def eat(self):  print('爸爸常常吃海鲜')  pass  class Son(Father):  pass  son = Son() print(Son.__mro__)  ## 定义跟父类相同的方法,能够实现覆盖和重写父类的方法 复制代码

2.4重写初始化方法

class Grandfather():
 def __init__(self,name):  self.name = name  pass  def eat(self):  print('吃的方法')  pass  pass  class Father(Grandfather):  def __init__(self):  pass  ## 覆盖了父类的方法  def eat(self):  print('爸爸常常吃海鲜')  pass  class Son(Father):  pass  son = Son() print(Son.__mro__) 复制代码

2.5调用父类初始化方法

class Father:
 def __init__(self,name):  self.name = name  pass   ## 覆盖了父类的方法  def eat(self):  print('爸爸常常吃海鲜')  pass  class Son(Father):  def __init__(self,name):  Father.__init__(self,name) ##调用父类的方法,能够具有name属性  ## 或者  ## super.__init__(name) ##也能够这样写  self.age = 90 ## 添加新的实例方法  self.sex = '男'  pass  pass  son = Son('hello')  复制代码

2.6 调用父类的方法

class Father:
 def __init__(self,name):  self.name = name  pass   ## 覆盖了父类的方法  def eat(self):  print('父类的吃方法')  pass  class Son(Father):  def __init__(self,name):  Father.__init__(self,name) ##调用父类的方法,能够具有name属性  ## 或者  ## super.__init__(name) ##也能够这样写  self.age = 90 ## 添加新的实例方法  self.sex = '男'  pass  pass   def __str__(self):  print('{}'.format(self.name))  pass   def eat(self):  super().eat() ##调用父类的方法  print('子类的吃方法')  pass  son = Son('詹躲躲') son.eat()  ## 父类的吃方法 ## 子类的吃方法 复制代码

3 多态

同一种行为,对于不一样子类【对象】有不一样的实现方式web

3.1 要想实现多态,必须有两个前提

1.继承:发生在父类和子类之间数据库

2.重写:子类重写父类的方法编程

3.1 案例演示编辑器

class Animal:
 ## 基本类  def say(self):  print('动物类')  pass  pass  class Duck(Animal):  ## 子类 派生类  def say(self):  print('鸭子类')  pass  pass  class Dog(Animal):  ## 子类 派生类  def say(self):  print('小狗类')  pass  pass  ## duck1 = Duck() ## duck1.say()  ## dog = Dog() ## dog.say()   def commonIvoke(obj):  ## 统一调用  obj.say()  ## 循环统一调用 listObj = [Duck(),Dog()] for item in listObj:  commonIvoke(item)  ## 在定义时的类型跟调用时不同的时候,称为多态。 复制代码

3.2 多态的好处

1.增长程序的灵活性ide

2.增长程序的扩展性函数

4.类属性和实例属性

## 类属性:就是类对象拥有的属性,它被全部类对象的实例对象所共有,类对象和实例对象能够访问。
## 实例属性:实例对象所拥有的属性,只能经过实例对象访问。  class Student:  ## 类属性  name = '叫我詹躲躲'  def __init__(self,age):  self.age = age  pass  pass  lm = Student(18)  ## 经过实例对象去访问类属性 print(lm.name) print(lm.age)  ## 经过类对象去访问 print(Student.name) print(Student.age)  ## 总结 ## 类属性:类对象和实例对象均可以访问 ## 实例属性:只能由实例属性访问  ## 全部的实例对象指向同一类对象 ## 实例对象去修改类属性 不能修改 ## 类对象能够修改类属性 能够修改  复制代码

5.类属性和静态方法

## 装饰器@classmethod
class Person:  country = 'china'   ## 类方法 用classmethod修饰  @classmethod  def get_country(cls):  return cls.country ## 访问类属性  pass  @classmethod  def change_country(cls):  cls.country = 'America'  pass  ## 经过类对象去引用 print(Person.get_country()) print(Person.change_country()) print(Person.get_country()) 复制代码

5.1 静态方法

class Person:
 country = 'china'   ## 类方法 用classmethod修饰  @classmethod  def get_country(cls):  return cls.country ## 访问类属性  pass  @classmethod  def change_country(cls):  cls.country = 'America'  pass  @staticmethod  def get_data():  return Person.country  pass  ## 经过类对象去引用 print(Person.get_country()) print(Person.change_country()) print(Person.get_country()) print(Person.get_data()) 复制代码

通常不会经过是实例对象去访问静态方法post

因为静态方法主要存放逻辑方法,自己与类以及实例没有交互,也就是不会涉及类中方法和属性的操做网站

根据资源可以有效的利用spa

5.2求系统当前的时间

import time
class sys_time:  def __init__(self,hour,min,second):  self.hour = hour  self.min =min  self.second = second   @staticmethod  ## 独立的功能  def show_time():  return time.strftime('%H:%M:%S',time.localtime()) print(sys_time.show_time()) ## 15:15:44  复制代码

5.3 总结

1.类方法的第一个参数是类对象,cls进而去引用类对象的属性和方法

2.实例方法的第一个参数是实例属性,若存在相同的实例属性或者方法,实例属性优先级最高

3.静态方法不须要额外的参数,若须要引用属性。,则能够经过类对象或者实例对象去引用便可,必须使用装饰器@staticmethod装饰

6.私有化

6.1 私有化属性

## 私有属性 以__开头,声明为属性私有,不能在类的外部被使用或者直接访问。
 class Person(object):  def __init__(self):  self.__name = '叫我詹躲躲' ## 私有化  self.age = '21'  pass  def __str__(self):  return '{}的年龄是{}'.format(self.__name,self.age)  person = Person() ## print(person.__name) ##报错 print(person) ##能够访问 ## 叫我詹躲躲的年龄是21  ## 私有属性,不能被子类继承 复制代码

6.2私有化方法

class A(object):
 def __eat(self):  print('吃饭')  pass  pass   def run(self):  print('跑步')  pass  pass  b = A() b.__eat() ## 报错 b.run() ## 跑步 复制代码

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() 复制代码
相关文章
相关标签/搜索