面向对象,多态:

有时一个对象会有多种表现形式,比如网站页面有个按钮, 这个按钮的设计可以不一样(单选框、多选框、圆角的点击按钮、直角的点击按钮等),尽管长的不一样,但它们都有一个共同调用方式,就是onClick()【鼠标单击】方法。我们直要在页面上一点击就会触发这个方法。点完后有的按钮会变成选中状态、有的会提交表单、有的甚至会弹窗。这种多个对象共用同一个接口,又表现的形态不一样的现象,就叫做多态( Polymorphism )。

例如:人会吃,猪也会吃,牛也会吃,那都是吃,这吃就是一个接口,但是,每个吃的方式又不一样。多个对象共用一个接口就是多态

  1. #我们定义一个车类,他们都有共同的方法,启动和刹车。
  2. #但是不同的车的启动方法不一样,比如说,卡车可能用钥匙启动,跑车电子启动。
  3. #刹车的时候,跑车直接刹车就好了,但是卡车有时候就不敢直接刹车需要点刹
  4.  
  5. class Car:#定义一个车类
  6. def __init__(self, name):
  7. self.name = name
  8. def drive(self):
  9. raise NotImplementedError("子类必须实现抽象方法")#异常处理后面说
  10. #意义就是,你可以调用我得方法,但是子类必须自行实现自己得方法,不然就报错
  11. def stop(self):
  12. raise NotImplementedError("子类必须实现抽象方法")
  13. class SportsCar(Car):#跑车类继承车类
  14. #继承父类的init方法
  15. def drive(self):
  16. return '开动'
  17. def stop(self):
  18. return '点刹'
  19. class Truck(Car):#卡车继承车类
  20. #继承父类的init方法
  21. def drive(self):
  22. return '卡车开得慢是因为负载过重.'
  23. def stop(self):
  24. return '装有钢管,不敢直接刹车,不然车头不见啦!'
  25.  
  26. # cars = [Truck('东风重卡'),
  27. # Truck('三一重工'),
  28. # SportsCar('法拉利')]
  29.  
  30. cars = Truck('东风卡车')
  31. cars1 = SportsCar('法拉利')
  32. print(cars.stop())#装有钢管,不敢直接刹车,不然车头不见啦!
  33. print(cars1.stop())#点刹
  34. #这2个实例都使用的共同的方法
  35. # for car in cars:
  36. # print(car.name + ': ' + car.drive())

封装:

封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。要访问该类的代码和数据,必须通过严格的接口控制。封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。适当的封装可以让程式码更容易理解与维护,也加强了代码数据的安全性。

优点:

1. 良好的封装能够减少耦合。

2. 类内部的结构可以自由修改。

3. 可以对成员变量进行更精确的控制。

4. 隐藏信息,实现细节。

在参数里面 加上__ 双下划线 ,就是实现了封装属性

  1. #如果你定义一个类之后,有的参数不想让人直接调用,或者修改的话,就需要封装了
  2. class Room:#定义个房子类
  3. def __init__(self,name,owner,width,length,high):
  4. self.name=name
  5. self.owner=owner
  6. self.__width=width# 在变量前面 加__ 2个下划线就把数据属性封装了。再实例中就不可以直接调用了也不能修改了
  7. self.__length=length
  8. self.__high=high
  9.  
  10. def tell_area(self): #此时我们想求的是面积
  11. return self.__width * self.__length *self.__high
  12.  
  13. def tell_width(self):#这样函数外面就可以调用了
  14. return self.__width
  15.  
  16. r1=Room('卫生间','alex',100,100,10000)
  17. print(r1.name)#这个参数没有封装,所以可以直接调用
  18. r1.name = '卧室'
  19. print(r1.name)#也可以修改
  20. # r1.width# 这样就不能调用,报错哦
  21. r1.tell_width() #这个实际上在调用函数的方法调用到了width的值
  1. #在python的一个约定,一般单下滑线的变量,一般不希望调用。但是不限制你调用,你想调用也行。
  2. #使用者碰到定义者用_线写得变量,经量还时不要调用

类的反射:主要指陈旭可以访问、检测和修改他本身状态或者行为的一种能力

下列方法适用于类和对象

hasattr(OBJ,name): 判断一个对象里面有没有这个属性name(字符串)

#判断OBJ中有没有一个name字符串对应的方法或者属性

getattr,

#获取一个类的的属性

setattr:设置实例属性

delattr: 删除

  1. class Person:#定义一个人类
  2. def __init__(self,name,age):
  3. self.name = name
  4. self.age = age
  5. def say_hi(self):
  6. print("hi,honey , my name is " ,self.name)
  7. obj=Person('SJC',26)
  8. #检测是否含有某属性
  9. print(hasattr(obj,'name'))#检查有没有这个变量
  10. print(hasattr(obj,'say_hi'))#检查有没有这个字符串
  11. #获取属性
  12. n=getattr(obj,'name')
  13. print(n)
  14. func=getattr(obj,'say_hi')
  15. func()
  16. print(getattr(obj,'aaaaaaaa','不存在啊')) #后面可以加参数,如果不存在就报错
  17. #设置属性
  18. setattr(obj,'XFD',"girl")#设置实例属性
  19. setattr(obj,'show_name',lambda self:self.name+'--%s' % self.age)#设置函数属性
  20. print(obj.__dict__)
  21. print(obj.show_name(obj))#必须添加一个参数
  22. # #删除属性
  23. delattr(obj,'age')
  24. delattr(obj,'show_name')
  25. #delattr(obj,'show_name111') # 不存在,则报错
  26. print(obj.__dict__)

Hasattr/getattr/delattr/setattr

动态导入模块:__import__#  如果是多目录导入,导入的要写路径

m = __import__('test1111')#模块路径 m.sun()#执行函数

#如果一个函数名以单下划线开头  那导入模块的时候,默认不会导入,使用的时候也要加上_单下划线

动态导入模块1:importlib

import importlib m = importlib.import_module("test1111")

#这个方式是导入的顶级模块,直接m.就可以运行

 内置:__setattr__、__deklattr__、__getattr__,定义到类中

  1. class Person:#定义一个人类
  2. gender = "man"
  3. def __init__(self,name,age):
  4. self.name = name
  5. self.age = age
  6. def __getattr__(self, item):
  7. print("执行__getattr__")
  8. def __delattr__(self, item):
    # self.__dict__.pop(item)系统应该是这么操作的
  9. print("执行__delattr__")
  10. def __setattr__(self, key, value):
  11. # self.key = value#RecursionError: maximum recursion depth exceeded
  12. #进入递归
  13. self.__dict__[key] = value
  14. #所有的设置属性,都是在调用属性字典
  15. print("执行__setattr__")
  16. def say_hi(self):
  17. print("hi,honey , my name is " ,self.name)
  18. obj=Person('SJC',26)
  19. # print(obj.name)#SJC
  20. # print(obj.alkf)#执行__getattr__
  21. #__getattr__调用不存在的属性时触发
  22. # del obj.age #执行__delattr__
  23. # del obj.gender#执行__delattr__
  24. #删除时,执行__delattr__
  25. obj.NB = "XFD" #设置成功
  26. print(obj.__dict__)

#这些都是内置的,如果你自己在自己得类中定义了,然就使用你自己定义的。如果没定义,那就使用系统内置的

#__delattr__setattr__ 不经常用

__getattr__的用法

  1. class Person:#定义一个人类
  2. gender = "man"
  3. def __init__(self,name,age):
  4. self.name = name
  5. self.age = age
  6. # def __getattr__(self, item):
  7. # return "你找的属性【%s】不存在" % item
  8. # def __delattr__(self, item):
  9. # print("执行__delattr__")
  10. def __setattr__(self, key, value):
  11. # self.__dict__[key] = value
  12. print("执行__setattr__")
  13. def say_hi(self):
  14. print("hi,honey , my name is " ,self.name)
  15. obj=Person('SJC',26)
  16. # print(obj.name)#SJC
  17. # print(obj.ada)#你找的属性【ada】不存在 #触发getattr

__getattr__用法

__setattr__用法:

需求:设置的值都为字符串。

  1. class Person:#定义一个人类
  2. gender = "man"
  3. def __init__(self,name):
  4. self.name = name
  5. def __setattr__(self, key, value):
  6. if type(value) is str:
  7. self.__dict__[key] = value
  8. return "设置成功"
  9. else:
  10. print('设置失败')
  11.  
  12. obj=Person(123)#
  13. # print(obj.name)

_setattr__

__delattr__ 就不用演示啦

包装内置方法:使用继承

备注:我们可以用用继承的方式来修改自定义 的一些方法。

例如:你想修改内置的list方法 ,你可以定义一个LIST 类,然后设置各类函数,比如定义一个,append 的类方法append只能添加字符串类型,然后再用上__setattr__  就可以自己定义功能了。【继承方法】

#class List(list):

授权:也是包装的一个特性。但是使用的是__getattr__。不用继承

例:定制自己文件操作时的写   方法,写入文本的时候,加入时间 别的方法不变。

  1. import time
  2. class FileHandle:
  3. def __init__(self,filename,mode='r',encoding='utf-8'):
  4. #默认参数,不填使用默认的。
  5. # self.filename=filename
  6. self.file=open(filename,mode,encoding=encoding)
  7. self.mode = mode
  8. self.encoding = encoding
  9. def write(self,line):
  10.  
  11. #line 就是你调用write写入的值
  12. t=time.strftime('%Y-%m-%d %X')#定义时间格式
  13. self.file.write('%s %s' %(t,line))#T时间,line写入的内容
  14. #在写入时自动加上时间
  15. def __getattr__(self, item):
  16. # print(item,type(item))
  17. # self.file.read
  18. return getattr(self.file,item)
  19. #因为item传进来,是个字符串,getattr的功能就是获取字符串功能参数是字符串
  20. #你在实例化的时候,传入的时候,没有那个值,就是触发getattr.
  21. #出入getattr之后,我们返回file.那就启动了init的方法
  22.  
  23. f1=FileHandle('a.txt','w+')
  24. print(f1.file)
  25. print(f1.__dict__)
  26. print('==>',f1.read) #触发__getattr__
  27. print(f1.write)
  28. #f1.read执行后,然后系统会寻找init,init没有,去找类,类也没有,就出发_getattr_然后使用系统内置的open
  29. #f1.write执行后,系统寻找init,没有,找类,类有write方法,write方法,返回
  30. f1.write('cpu负载过高\n')
  31. f1.write('内存剩余不足\n')
  32. f1.write('硬盘剩余不足\n')

定制文件写操作

Day 20: 面向对象【多态,封装,反射】字符串模块导入/内置attr /包装 /授权的更多相关文章

  1. Py修行路 python基础 (十八) 反射 内置attr 包装

    一.isinstance 和 issubclass1.isinstance(obj,cls)检查是否obj是否是类 cls 的对象.2.issubclass(sub, super)检查sub类是否是 ...

  2. 多态,封装,反射,类内置attr属性,os操作复习

    1.多态 #多态 多态是指对象如何通过他们共同的属性和动作来操作及访问,而不需要考虑他们具体的类 运行时候,多种实现 反应运行时候状态 class H2O: def __init__(self,nam ...

  3. CSIC_716_20191129【面向对象高级----反射、类的内置方法(魔法方法)、单例模式】

    反射 反射是通过'字符串'对 对象的属性进行操作,反射有四个内置的方法. hasattr 通过字符串 判断对象的属性或者方法是否存在 getattr 通过字符串  获取对象的属性或者方法        ...

  4. Python:数字类型和字符串类型的内置方法

    一.数字类型内置方法 1.1 整型的内置方法 作用 描述年龄.号码.id号 定义方式 x = 10 x = int('10') x = int(10.1) x = int('10.1') # 报错 内 ...

  5. JavaScript封装一个函数效果类似内置方法concat()

    JavaScript封装一个函数效果类似内置方法concat() 首先回忆concat()的作用: concat() 方法用于连接两个或多个数组.该方法不会改变现有的数组,而仅仅会返回被连接数组的一个 ...

  6. day006 数字类型和字符串类型的内置方法

    首先,为什么要有数据类型? 对于不同类型的变量,需要用不同的数据类型去描述. 数字类型的内置方法 数据类型又分为整形和浮点型.以下所述的内置方法均适用于这两个类型. 必须掌握的方法*** 数据类型有基 ...

  7. python字符串——"奇葩“的内置函数

      一.前言 python编程语言里的字符串与我们初期所学的c语言内的字符串还是有一定不同的,比如python字符串里的内置函数就比语言的要多得多:字符串内的书写格式也会有一点差异,例:字符串内含有引 ...

  8. day29 Pyhton 面向对象 多态 封装

    # coding:utf-8 # py2中的经典类 # class D:#没有继承object是经典类# pass # # def func(self): # # print('d') # class ...

  9. Day07:常用模块,面向对象编程(对象&类)及内置函数

    今日内容:1.常用模块2.面向对象编程(*****)    介绍面向对象编程    类    对象3.内置函数------------------------------1.面向过程编程    核心“ ...

随机推荐

  1. JS制作二级联动

    JS制作二级联动 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://ww ...

  2. linux SMbus错误

    针对piix4_smbus ****host smbus controller not enabled的解决方法 查看文件并用超级权限修改内容 在末尾加入blacklist i2c——piix4 重启 ...

  3. 数据持久化之Android文件系统(一)

    阿里P7Android高级架构进阶视频免费学习请点击:https://space.bilibili.com/474380680 一.前言 文件系统一直是Android开发过程中经常接触的东西.而关于内 ...

  4. hive HQL笔记

    #建表 create table sign_in (uri string , test string) row format delimited fields terminated by '|'; # ...

  5. 装完某些软件之后IE主页被https://www.hao123.com/?tn=93453552_hao_pg劫持

    今天重装电脑,装完某些软件之后发现IE主页被https://www.hao123.com/?tn=93453552_hao_pg劫持,然后百度各种解决方法都没用,甚至是修改注册表依然没啥用 最后忽然看 ...

  6. vue-cli3使用cdn引入

    1. index.html引入: <script src="https://cdn.bootcss.com/moment.js/2.20.1/moment.min.js"&g ...

  7. grep中正则表达式使用尖括号表示一个单词

    比如 grep '\<bin\>' /etc/passwd --color

  8. 笔记67 Spring Boot快速入门(七)

    SpringBoot+RESTful+JSON 一.RESTful架构 REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移. ...

  9. mysql莫名报"unknown column ... in 'on clause'"

    今天遇见个会诡异的问题 一个web程序本地调试的好好的,结果发布到服务器上程序就报错了,报"unknown column ... in 'on clause'",网上搜了下,说是m ...

  10. day08 python文件操作

    day08 python   一.文件操作     1.文件操作的函数         open(文件名, mode=模式, encoding=字符集)       2.模式: r, w, a, r+ ...