文章目录
- Python基础之面向对象
- 面向对象的三大特性
- 类和对象的关系
- 类的组成
- 类的书写规则
- 实例化对象
- 检测类和对象的成员
- 类和对象成员的操作
- 类成员操作
- 对象成员操作
- 关于self
- 封装特性
- 私有化封装 private
- 受保护的封装 protected
- 公共的封装 public
- 继承
- 继承的格式
- 继承的特征
- 单继承和多继承
- 菱形继承/钻石继承
- MRO列表
- super()
- mixin 设计模式
- 魔术方法
- 常用魔术方法
- 1.\__init__
- 2.\__new__
- 3.\__del__
- 4.\__call__
- 5.\__len__
- 6.\__str__
- 7.\__repr__
- 8.\__bool\__
- 9.\__format__
- 描述符相关的魔术方法
- 1.\__get__()
- 2.\__set__()
- 3.\__delete__()
- 与属性操作相关的魔术方法
- 1.\__getattr__()
- 2.\__setattr__()
- 3.\__delattr__()
- 4.\__getattribute__()
- 5.\__dir__()
- 运算相关魔术方法(上帝模式)
- 比较运算相关魔术方法
- 1.\__lt__()
- 2.\__le__()
- 3.\__gt__()
- 4.\__ge__()
- 5.\__eq__()
- 6.\__ne__()
- 算术运算相关魔术方法
- 反运算相关魔术方法
- 赋值运算相关魔术方法
- 一元运算相关魔术方法
- 类型转换相关魔术方法 JIANG
- 上下文管理相关魔术方法
- 容器类型相关魔术方法
- 类的常用函数
- 描述符
- 类的内置属性
- 装饰器
- 方法的分类
- 抽象类
- 抽象类的语法
- 抽象类的特征:
- 多态
Python基础之面向对象
面向对象的三大特性
面向对象都具有三大特性:封装,继承 和 多态
类和对象的关系
类是多个对象归纳总结而来的,是一种概念,包含所有对象。
由对象总结出类的过程,叫做抽象化
对象是类的具体实现或者实施而来,他是真实的,特指某个事物。
由类制作出对象的过程,叫做实例化
类的组成
类中只有2种内容:成员属性和成员方法
成员属性:用于描述类的特征的变量就是成员属性成员方法:用于描述类的功能的函数就是成员方法
类的书写规则
- 必须使用class关键字来声明一个类
- 类的名称需要符合驼峰命名法(规范)
- 类中只能存在2种内容,成员属性和成员方法,除此之外,所有的代码都禁止出现!
- 声明成员属性时,所有成员属性必须有值,如果没值会报错!,推荐使用None等值代替
- 成员方法只需要按照函数的规则声明即可
实例化对象
实例化对象格式
对象变量 = 类()
类的类型为 type
<class 'type'>
类的值就是类本身
<class '__main__.Person'>
对象的类型为类
<class '__main__.Person'>
对象的值,对象本身
<__main__.Person object at 0x020DC650>
class GirlFriend:#属性sex = '女'age = 18height = '170'weight = '50kg'#方法def guan(self):print('逛逛!~~~')def eat(self):print(self)print('吃吃~~~')def cry(self):print('呜呜呜呜~')
检测类和对象的成员
检测类成员
类名.__dict__
检测对象成员
对象.__dict__
类和对象成员的操作
类成员操作
访问类中成员类名.成员属性名类名.成员方法名() (没有参数要求,所有方法都可以通过类访问)修改类中成员类名.成员属性名 = 值类名.成员方法名 = 新值 (如果需要函数只能用lambda)删除类中成员del 类名.成员属性名del 类名.成员方法名添加类中成员类名.新成员属性名 = 值类名.新成员方法名 = 值 (如果需要函数只能用lambda)
对象成员操作
访问对象中成员对象变量.成员属性名对象变量.成员方法名() (必须有一个用于接收对象本身的形参)修改对象中成员对象变量.成员属性名 = 值对象变量.成员方法名 = 新值 (如果需要函数只能用lambda)删除对象中成员del 对象变量.成员属性名del 对象变量名.成员方法名添加对象中成员对象变量.新成员属性名 = 值对象变量.新成员方法名 = 值 (如果需要函数只能用lambda)
#访问
print(GirlFriend.sex)#属性
GirlFriend.eat(1)#方法#修改
print(GirlFriend.age)
GirlFriend.age = 38#属性
print(GirlFriend.__dict__)#定义一个函数
def mycry():print('小姑娘,你别哭,来叔叔给你棒棒糖吃~')
GirlFriend.cry = lambda : print('啊呜啊呜啊呜啊呜~')#方法
GirlFriend.cry = mycry#方法
GirlFriend.cry()#添加
GirlFriend.hobby = '玩枪'#属性
print(GirlFriend.__dict__)
GirlFriend.upsky = lambda : print('111!')#方法
GirlFriend.upsky()#删除
del GirlFriend.upsky
print(GirlFriend.__dict__)
del GirlFriend.cry
print(GirlFriend.__dict__)
关于self
他不是关键字,是一个随意书写的字符串而已
1.英文单词的意义 :自己
2.绑定类的方法,只能通过类来访问的方法,就是绑定类的方法
3.非绑定类的方法,就是可以通过对象访问的方法就是非绑定的方法
4.绑定类与非绑定类的方法不取决于语法,而取决于设计者如何设计该方法
5.一般情况下非绑定类的方法第一个参数写单词self,但是这不是唯一的单词,写什么都行,self不是关键字,不是关键字,不是关键字!
class Human:#属性 -> 成员属性(变量)ear = 2mouth = 1sex = 'man'age = 28name = '章旺'married = Falsecolor = 'yellow'hair = None#特征 -> 成员方法(函数)def walk(self):print('直立行走')def eat(self):print('吃饭饭')def sleep(self):print('睡觉觉')def playgame(self):print('打游戏!')#查看类的值
print(Human)
#类的类型
print(type(Human))
#实例化对象操作
wangwang = Human()
#打印对象的值
print(wangwang)
#打印对象的类型
print(type(wangwang))
#检测类的成员(在类中声明的成员都可以看到)
print(Human.__dict__)
#检测对象中的成员
print(wangwang.__dict__)
print(wangwang.sex)
封装特性
封装就是对类和对象的成员访问进行限制,设定可以访问的方式和不可以访问的方式。
封装的三个级别:
私有化封装 -> private 英文单词而已不是关键字
受保护的封装 -> protected 英文单词而已不是关键字
公共的封装 -> public 英文单词而不是关键字
检测封装的三个位置:
类中/对象中
类外部/对象外部
子类中
私有化封装 private
私有化封装是最高级别的封装。私有化封装之后的成员,只能在类中/对象中访问,类的外部,子类中都不可以访问到。
私有化封装:在成员名称前添加2个_即可
例如:封装heart -> __heartpython将heart 改名为 _类名__成员名 封装后的访问限制:类中/对象中 可以访问类外/对象外 不可以访问子类/子类对象 不可以访问
**注意:**在python中实现的封装操作,不是通过权限限制而是通过改名(name mangling 改名策略)实现的,名字变了找不到而已。
可以通过 对象.类名 __方法或类名.类名 __方法名访问到(但禁止这么干)
class Human:#属性age = 18#私有化封装成员属性[只能在当前结构中使用]__sex = '男'color = 'yellow'hair = '黑色'#方法def say(self):print('阿姨啊~~~')def walk(self):print('嗖嗖的~')#私有化成员方法[只能在当前类或者对象的结构中访问]def __niao(self):print('嘘嘘~~')#测试:自己访问自己的私有成员def demo(self):#访问私有方法niaoself.__niao()print('测试私有成员的访问')
受保护的封装 protected
受保护的封装是一定级别的封装,封装之后,只有部分位置可以访问(类和子类),部分位置(类外)不可以访问。
受保护的封装: 在成员名称前添加1个_即可
例如:受保护 money -> _money封装后的访问限制:类中/对象中 可以访问类外/对象外 可以访问(原则上类外不行,但是没实现)子类/子类对象 可以访问
**注意:**受保护的封装依旧是通过name mangling的方式修改了成员的名称而已。
可以通过对象.类名成员 或者类名.类名成员的方式访问(但也别这么干)
#python语法中没有受保护的语法,程序员约定一种操作来实现受保护class Father:#属性sex = 'man'#受保护的_money = 1000color = 'yellow'#私有化__wife = '小泽亚'#方法def eat(self):print(Father._money)print('吃吃吃吃~~')def niao(self):print('哗哗哗哗~~')class Son(Father):#添加一个子类的方法用于测试子类中的访问def test():#方式访问父类中私有成员#print(Father.wife)#print(Son.wife)#访问父类中公共的成员#print(Son.color)#访问受保护的成员print(Son._money)Son.test()
#Father.eat(1)
#print(Father._money)
#受保护的定义
'''
私有化:只能载类或者对象的结构中访问
公共的:可以载任何位置访问
受保护:可以载当前类或者对象 和子类或者子类对象中访问类内 子类中 类外部
私有化: √ X X
受保护: √ √ √(X类外部应该不能访问!)
公共的: √ √ √ '''
公共的封装 public
所有的成员默认都是公共的封装级别,可以在类中,类外,及子类中正常访问
类中/对象中 可以访问
类外/对象外 可以访问
子类/子类对象 可以访问
继承
继承就是可以获取另外一个类中的成员属性和成员方法。(并非所有成员)
**作用:**继承的作用是增加代码的复用性,节省不必要的重复代码,提高开发效率,同时可以设置类之间的关系。
继承的两个概念:
父类用于被继承的类,称之为父类,也叫做基类,或者超类
子类继承其他类的类,称之为子类,也叫做派生类
继承的格式
class 父类:pass
class 子类(父类):#继承操作的关键步骤pass
继承的特征
1.所有类都是继承自object类(object类对应的对象就是object对象,也是万物皆对象)
2.子类继承父类则可以访问父类的所有成员。(私有成员除外)
3.子类继承父类并不会将父类的所有成员复制到子类当中去,访问父类成员是间接通过父类来访问的,
4.子类可以具有自己独有的属性和方法
5.子类可以重载父类中的方法,只需要设置和父类指定成员相同的名称即可实现重载,重载之后的成员,子类只会访问当前类中的成员,而不会调用父类中同名的成员
6.子类中如果重载父类的方法,并且还想将重载的父类方法借调过来使用,可以在重载的方法中使用如下方法
[父类名.方法()](适合类) 或者 [super().方法()](适合对象)
#刘备类:父类-》被其他类继承的类称之为父类(超类,基类)
class LiuBei:#属性familyname = '刘'firstname = '备'sex = 'man'money = '$100'country = '蜀国'#私有成员__wife = ('甘夫人','糜夫人','孙尚香')#方法def say(self):print('你这个小子,险些损我一员大将')#f非绑定类的方法[对象访问]def drink(self):print(self)print('来,干了这杯酒')def walk(self):print('gogo,fire in the hole')#绑定类的方法def la():print('哗啦啦啦啦啦~~')
#刘禅类:子类-》继承其他类的类称之为子类(派生类)
class LiuChan(LiuBei):#子类独有的成员#属性weight = '180斤'#方法def douququ(self):print('此间乐,不思蜀')#重载父类方法def say(self):print('我爸爸是刘备')#重载父类的drink方法,但是还要将父类中操作拿过来使用def drink(self):print('举起筷子,夹一口菜')#喝酒 通过对象调用的方法的重载(推荐使用super().方法名())super().drink()#LiuBei.drink(self)## 重载父类的drink方法,但是还要将父类中操作拿过来使用def la():print('准备好擦屁股纸!~')#调用父类的la方法(推荐使用类名.方法名)LiuBei.la()#查看刘禅类
#print(LiuChan.__dict__)#继承操作不会将成员直接复制到子类中
#print(LiuChan.sex)
#LiuChan.walk(1)
#print(LiuChan.wife)#result = issubclass(type,object)
#print(result)#访问子类独有的成员
#LiuChan.douququ(1)
#print(LiuChan.weight)#访问继承来的方法
#LiuChan.say(1)#访问重载并且调用了父类的方法的方法
#LiuChan.la()lc = LiuChan()
lc.drink()
单继承和多继承
**单继承:**每个类只能继承一个类的方式称为单继承。
**多继承:**每个类可以同时继承多个类的方式称为多继承。
python属于多继承语言!但是一般不用
多继承格式:
class 父类1:passclass 父类2:passclass 子类(父类1,父类2):pass
多继承之后,子类就具备了所有父类的成员(私有成员除外)
多个父类具有相同的成员时,子类继承[继承列表]中第一个类的方法
菱形继承/钻石继承
菱形继承格式
class A:passclass B(A):passclass C(A):passclass D(B,C):passA/ \B C\ /D
菱形继承存在的问题
如果BC类同时继承了A类,D类又继承了BC两个类的情况下(菱形继承),
在调用BC中某个同名方法(该方法都继承自A类)时会导致继承自A类的该方法被多次调用。产生逻辑问题!
所以python使用 super() 类来解决了多继承的菱形继承问题
MRO列表
Method Realtion Order 用来制作一个继承关系的列表
python3中使用C3算法来计算MRO列表(计算过程暂时忽略)
MRO列表的制作原则:
1.子类永远在父类的前面
2.如果继承了多个父类,那么按照()中的顺序在列表中摆放
3.如果多个类同时继承了一个父类,孙子类中只会选取第一个父类中的父类的该方法
#菱形继承
'''动物类人类 鸟类鸟人类
'''
#动物类
class Animal:#属性pass#方法def say(self):print('Animal张开嘴')print('Animal合上嘴')
#人类
class Human(Animal):#属性pass#方法def say(self):print('人类张开嘴')#调用动物类的say方法super().say()print('人类合上嘴')
#鸟类
class Bird(Animal):#属性pass#方法def say(self):print('鸟类张开嘴')# 调用动物类的say方法super().say()print('鸟类合上嘴')
#鸟人类
class BirdHuman(Human,Bird):#属性pass#方法def say(self):print('鸟人类张开嘴')#鸟类的say#人类saysuper().say()print('鸟人类合上嘴')
#实例化鸟人对象
bh = BirdHuman()
bh.say()#MRO(Method Resolution Order):方法解析顺序。 里面采用c3算法进行排序
#查看继承关系的mro列表
result = BirdHuman.mro()
print(result)#MRO列表 C3算法 将继承关系的类做成一个列表
#1.子类永远在父类的前面
#2.如果同时继承多个类,谁在继承格式中考前,在列表中也靠前
#[鸟人类,人类,鸟类,动物类,Object] MRO列表
#super() 永远获取MRO列表的下一个类
super()
super不是一个关键字,也是不是有函数,他是一个类
super()的作用不是查找父类,而是找MRO列表的下一个类
super()和父类没有任何实质性的关系,只是有时候能调用到父类而已。
在单继承的情况下,super()永远调用的是父类/父对象
格式:
super().方法() #python3的格式
多继承按需操作,在没有必要的时候避免强行使用!
mixin 设计模式
该设计模式的主要作用是采用多继承方式,进行类的扩展。
优点:
- mixin可以在对类不做任何修改的情况下,扩展类的功能(添加父类)
- 可以方便的组织和维护各种不同组件的划分。
- 可以根据需要任意调整
- 可以避免创建更多的类,也可以避免继承导致的混乱
#水果类
class Fruit:pass
#礼物类和非礼物类
class Gift:pass
class NotGift:pass
#南方北方类
class South:pass
class North:pass
#爽和不爽的苹果
class Cool:pass
class NotCool:pass
#真实水果类
class Apple(Fruit,Gift,North,NotCool):pass
class Pear(Fruit,NotGift,North,NotCool):pass
class Banana(Fruit,NotGift,North,Cool):pass
class Orange(Fruit,Gift,South,NotCool):pass
魔术方法
常用魔术方法
魔术方法就是一个类/对象中的方法,和普通方法唯一的不同时,普通方法需要调用!而魔术方法是在特定时刻自动触发。
1._init_
初始化魔术方法
触发时机:初始化对象时触发(不是实例化触发,但是和实例化在一个操作中)
参数:至少有一个self,接收对象
返回值:无
作用:初始化对象的成员
注意:使用该方式初始化的成员都是直接写入对象当中,类中无法具有
import random
class Human:#属性age = 1color = 'yellow'#方法def __init__(self,diyname):#为对象添加成员#print(self)self.hair = '自然卷'self.name = diyname#随机产生性别if random.randrange(0,2) == 1:self.sex = '男'else:self.sex = '女'def eat(self):print('吃卷饼啃猪蹄')def drink(self):print('喝自来水')#实例化对象
zw = Human('雪饼')
print(zw.__dict__)print(Human.__dict__)
2._new_
实例化魔术方法
触发时机: 在实例化对时触发
参数:至少一个cls 接收当前类
返回值:必须返回一个对象实例
作用:实例化对象
注意:实例化对象是Object类底层实现,其他类继承了Object的__new__才能够实现实例化对象。
没事别碰这个魔术方法,先触发__new__才会触发__init__
class Human:#属性age = 18sex = 'man'#方法def __new__(cls,diyname):#print('new方法被触发')print(cls)return object.__new__(cls)def __init__(self,diyname):passdef sleep(self):print('教室睡觉真香甜')def eat(self):print('吃蛋蛋炒饭!')#实例化对象
sy = Human('小洋洋') #1.创建对象(new) 2.对对象进行初始化操作(init)
print(sy)
单例设计模式
class WangYingSong:#属性color = '黄色'age = 27name = '应松'#声明了一个类成员属性用于保存创建的对象obj = None#方法def __new__(cls):#检测是否已经制作国对象if cls.obj == None:#没有做过对象#实例化对象(存入当前类中)cls.obj = object.__new__(cls)return cls.objelse:#做过对象,直接将类中保存的对象返回return cls.objdef study(self):print('好好学习天天想上!~')def eat(self):print('吃肯德基全家捅!')#实例化对象1
ys1 = WangYingSong()
print(ys1)#实例化对象2
ys2 = WangYingSong()
print(ys2)#实例化对象3
ys3 = WangYingSong()
print(ys3)
3._del_
析构魔术方法
触发时机:当对象没有用(没有任何变量引用)的时候被触发
参数:一个self 结婚搜对象
返回值:无
作用:使用完对象是回收资源
注意:del不一定会触发当前方法,只有当前对象没有任何变量接收时才会触发
class Human:#属性money = 1000sex = 'man'age = 18name = '小松松'def __init__(self,sign):self.sign = sign#方法def eat(self):print('吃开塞露')def drink(self):print('和糖水~')#del魔术方法 析构方法def __del__(self):print(self.sign ,'del方法被触发')#实例化对象
ss = Human(0)
print(ss)
print('-------------------')
del ss
print('-------------------')'''sss
#将对象赋值给另外一个变量
ceshi1 = Human(1)
ceshi2 = Human(2)
print('-------------------')
'''
#文件读取操作
'''
1.打开文件
2.读取文件
3.关闭文件
'''
class ReadFile:#打开文件(构造)def __init__(self,filename):os.chdir(r'F:\python\python基础(√)\15\14')#打开文件将文件io对象保存载对象成员self.fp = open(filename, 'r',encoding='UTF-8')#读取文件def fread(self):return self.fp.read()#关闭文件(析构)def __del__(self):print('关闭文件操作')self.fp.close()#实例化对象
one = ReadFile('11.txt')txt = one.fread()
print(txt)
4._call_
调用对象的魔术方法
触发时机:将对象当作函数调用时触发 对象()
参数:至少一个self接收对象,其余根据调用时参数决定
返回值:根据情况而定
作用:可以将复杂的步骤进行合并操作,减少调用的步骤,方便使用
注意:无
#call魔术方法
'''
触发时机:把对象当作函数调用的时候自动触发
功能:简化操作
参数:至少一个self接受当前对象,其他参数根据程序决定
返回值:根据程序决定
'''
class Human:#属性sex = 'man'age = 18color = 'yellow'#方法def eat(self):print('吃饭饭')def sleep(self):print('睡觉觉')#def __call__(self):print('call魔术方法被触发')#实例化对象
bb = Human()
# print(bb)
#把对象当作函数调用的时候
bb()
#左蛋糕的类
class MakeCake:#和面def huomian(self):print('和面操作')#发酵def fajiao(self):print('发酵操作')#烘烤def hongkao(self):print('烘烤操作')#切形状def zaoxing(self):print('切形状')#抹奶油def monaiyou(self):print('抹奶油操作')#防水果def fangshuiguo(self):print('放水果操作')#打包def dabao(self):print('打包操作')return '完整的盒装蛋糕'#获取蛋糕的方法def __call__(self,who):print('制作者:',who)self.huomian()self.fajiao()self.hongkao()self.zaoxing()self.monaiyou()self.fangshuiguo()result = self.dabao()return result
#实例化对象
mc = MakeCake()#用户获取蛋糕
r = mc('从浩大厨')
print(r)
5._len_
触发时机:使用len(对象) 的时候触发
参数:一个参数self
返回值:必须是一个整型
作用:可以设置为检测对象成员个数,但是也可以进行其他任意操作
注意:返回值必须必须是整数,否则语法报错,另外该要求是格式要求。
#len魔术方法
'''
触发时机:使用len(对象)的时候自动触发
功能:用于检测对象中或者类中某个内容的个数
参数:只有一个self接受当前对象
返回值:必须返回整型
'''
class Human:#属性sex = 'man'age = 18color = 'yellow'size = '36E'#方法def eat(self):print('猪蹄+炸鸡')def drink(self):print('白开水一壶!')#魔术方法__len__def __len__(self):print('len方法被触发')#去掉带有下划线开头和结尾的成员#获取所有带有下划线的成员result = {k:v for k,v in Human.__dict__.items() if not ( k.startswith('__') and k.endswith('__'))}print(result)return len(result)#获取所有的成员# alls = Human.__dict__# 获取用户定义的普通成员个数 相减# return len(alls) - len(result)#实例化对象
mmf = Human()
print(mmf)result = len(mmf)
print(result)
6._str_
触发时机:使用print(对象)或者str(对象)的时候触发
参数:一个self接收对象
返回值:必须是字符串类型
作用:print(对象时)进行操作,得到字符串,通常用于快捷操作
注意:无
#str魔术方法
'''
触发时机:使用print打印对象的时候或者str(对象)都可以触发
功能:定义对象转换为字符串的结果
参数:一个self接受对象
返回值:必须返回字符串类型
'''
class Human:#属性sex = 'man'age =18name = '王成'#方法def la(self):print('拉妹子啦,拉妹子拉~')def sa(self):print('谁显开始?')#魔术方法__str__def __str__(self):#print('str被触发')#return '老王拉斯你!'return self.name#实例化对象
wc = Human()
print(wc)result = str(wc)
print(result)
7._repr_
触发时机:在使用repr(对象)的时候触发
参数:一个self接收对象
返回值:必须是字符串
作用:将对象转使用repr化为字符串时使用,也可以用于快捷操作
repr函数和str函数处理字符串只有一个区别:
str的结果 字符串本身 (结果可以被eval执行)
如:x = ‘无图言Diao’ str() ->无图言Diao
rerpr的结果 字符串定义结构 (eavl不会执行repr结果)
如:x = ‘无图言Diao’ repr() ->‘无图言Diao’
备注: 在类中通常情况下__str__和__repr__ 设置相同即可
eval()
函数 将字符串当作python代码执行
格式:eval(字符串)
返回值:可以有返回值
#repr魔术方法
'''
触发时机:使用repr(对象)的时候触发
功能:定义repr函数的结果
参数:一个self接受当前对象
返回值:必须返回字符串类型
'''
class Human:#属性sex = 'woman'age = 18height = '178cm'#方法def think(self):print('大脑里面胡思乱想~')def dream(self):print('I have a dream')#__repr__魔术方法def __repr__(self):print('repr方法被触发')return '这是一个章旺的对象!'#设定__str__和__repr__的魔术方法相同__str__ = __repr__#实例化对象
zw = Human()
result = repr(zw)
print(result)#测试repr函数
var = '123'
print(var)
result = repr(var)
print(result,type(result))
8._bool_
触发时机: 使用bool(对象)的时候触发
参数:一个self接收对象
返回值:必须是布尔值
作用:根据实际情况决定,可以作为快捷方式使用
注意:仅适合于返回布尔值的操作
#bool魔术方法
'''
触发时机:使用bool(对象)的时候自动触发
功能:根据某个规则确定对象的布尔值转换结果
参数:一个self接受当前对象
返回值:必须是布尔类型
'''
class Human:#属性sex = 'woman'age = 18color = 'yellow'#方法def getMoney(self):print('好好学习天天赚钱~')def sendMoeny(self):print('随便花')#__ bool__魔术方法def __bool__(self):#print('bool方法被触发')#设置当前对象 男-》True 女 -》Falseif self.sex == 'man':return Truereturn False
#实例化对象
bb = Human()result = bool(bb)
print(result)
9._format_
触发时机:使用字符串.format(对象)时候触发
参数:一个self接收对象,一个参数接收format的{}中的格式,例如:>5
返回值:必须是字符串
作用:设置对象可以作为format的参数,并且自定义对象格式化的规则
注意:无
#format魔术方法class Human:#属性name = '峰峰'sex = 'man'age = 18#方法def lang(self):print('峰峰划船一身浪~')def show(self):print('来,看看我的峰大步大!~')#__format__魔术方法def __format__(self,arg):#print('format方法被触发')#print(arg)# > < ^#将arg(限定符号)进行拆分flag = arg[0] # @align = arg[1] # > < ^num = int(arg[2:])# 6#判断对其方式if align == '<':#左对齐result = self.name.ljust(num,flag)elif align == '>':#右对齐result = self.name.rjust(num, flag)elif align == '^':#剧中对其result = self.name.center(num, flag)return result#实例化对象
sf = Human()str1 = '{:#^10}去偷窥女宿舍~'#峰峰 -》 @@@@峰峰
#相当于arg=('#','^','10')
result = str1.format(sf)
print(result)
描述符相关的魔术方法
1._get_()
触发时机:在获取指定描述符操作的成员属性的值的时候触发
参数:1描述符对象本身,2描述符描述的属性所在的对象,描述符描述的对象的类
返回值:必须有,不然无法获取相应属性值
注意:仅在描述符中使用
2._set_()
触发时机:在设置或者添加指定描述符操作的成员属性的时候触发
参数:1描述符对象本身,2描述符描述的属性所在的对象,3要设置的值
返回值:无
注意:仅在描述符中使用
3._delete_()
触发时机:在删除指定描述符操作的成员属性的时候触发
参数:1描述符对象本身,2描述符描述的属性所在的对象
返回值:无
注意:仅在描述符中使用
#描述符相关的魔术方法#描述符类
class Decription:#成员属性 共享值的操作def __init__(self):self.var = '张正阳'#定义三个操作#获取成员属性def __get__(self,obj,cls):#self描述符对象 obj 接受描述的成员属性username的对象e cls 描述的成员属性username所在的类Email#print(obj,cl`s)#隐藏名字中间的一个字符result = self.var[0]+'*'+self.var[-1]return result#设置成员属性def __set__(self,obj,value):#self描述符对象 obj 接受描述的成员属性username的对象e value 设置的值#设置时候,默认添加思密达self.var = value+'思密达'#删除成员属性def __delete__(self,obj):#self描述符对象 obj 接受描述的成员属性username的对象e#删除self.var就可以删除username的访问操作#根据密码是否为空决定是否可以删除用户名if obj.password == '':del self.varelse:passclass Email:#属性#希望对用户名进行管控(不是权限管控,而是内容管控)username = Decription()#交接操作 将username的操作管控交给描述符类的一个对象password = '11123'#方法def login(self):print('登录操作')def logout(self):print('退出操作')#实例化对象
e = Email()#获取成员属性
#print(e.username)#设置成员属性
#e.username = '章旺'
#print(e.username)#删除成员属性
del e.username
print(e.username)
#描述符2class Email:#属性#username = ''password = ''#方法def __init__(self):#设置var对象成员为描述符的三个方法工作self.var = '杨俊'def login(self):print('登录操作')def logout(self):print('退出操作')#获取属性的操作def getusername(self):result = self.var[0] + '*' +self.var[-1]return result#设置属性的操作def setusername(self,value):self.var = value#删除属性的操作def delusername(self):#删除的时候对self。var进行操作del self.var#将username属性 交给property制定的函数管理username = property(getusername,setusername,delusername) #实例化对象
e = Email()#获取成员属性
#print(e.username)#设置成员属性
#e.username = '王健'
#print(e.username)#删除成员属性
del e.username
print(e.username)
#描述符3class Email:#属性#username = ''password = ''#方法def __init__(self):#为描述符添加的用于数据通讯的成员属性self.var = '匿名'def login(self):print('登录操作')def logout(self):print('退出操作')#获取操作@propertydef username(self):result = self.var[0] + '*' + self.var[-1]return result#设置操作@username.setterdef username(self,value):self.var = value#删除操作@username.deleterdef username(self):del self.var#实例化对象
e = Email()#获取用户名
#print(e.username)#修改用户名
#e.username = '董伟'
#print(e.username)#删除用户名
del e.username
print(e.username)
与属性操作相关的魔术方法
1._getattr_()
触发时机:获取不存在的对象成员时触发
参数:1接收当前对象的self,一个是获取成员名称的字符串
返回值:必须有值
作用:为访问不存在的属性设置值
注意:getattribute无论何时都会在getattr之前触发,触发了getattribute就不会在触发getattr了
2._setattr_()
触发时机:设置对象成员值的时候触发
参数:1个当前对象的self,一个是要设置的成员名称字符串,一个是要设置的值
返回值:无 过程操作
作用:接管设置操作,可以在设置前之前进行判断验证等行为
注意:在当前方法中无法使用成员=值的方式直接设置成员,否则会无限递归,必须借助object的设置方法来完成object.__setattr__(参数1,参数2,参数3)
3._delattr_()
触发时机:删除对象成员时触发
参数:一个当前对象的self
返回值:无
作用:可以在删除成员时进行验证。
4._getattribute_()
触发时机:使用对象成员时触发,无论成员是否存在
参数:1个接收当前对象self,一个是获取的成员的名称字符串
返回值:必须有
作用:在具有封装操作(私有化时),为程序开部分访问权限使用
#与属性相关的魔术方法class Man:#属性sex = 'man'age = 18color = 'yellow'name = '石志朋'#方法def __init__(self):self.gf = '白石茉莉奈'self.hobby = '看CCAV播放的小丁丁历险记!'def chou(self):print('pia,pia老婆我错了~~')def keng(self):print('坑娃娃的爸爸~')"""#__getattr__()'''触发时机:访问一个不存在的成员属性的时候触发功能:1.防止访问不存在成员报错 2.可以为不存在的成员设置默认值参数:一个self接受对象 一个参数接受要访问的不存在的成员名返回值:可以有可以没有,但是如果有则是设置了访问的成员的值'''def __getattr__(self,attrname):#print(attrname)#通常载此处进行判断 决定返回什么值if attrname == 'height':return '175cm'elif attrname == 'weight':return '75kg'else:return '对不起不存在该属性'""""""#__getattribute__()'''触发时机:访问对象成员时触发(无论是否存在!)功能:可以限制过滤制定成员的值的访问参数:一个self接受当前对象 一个接受要访问的成员名返回值:可以有,可以没有 推荐根据程序设定(一般有!)'''def __getattribute__(self,attrname):if attrname == 'name':#不能够通过当前对象访问成员(访问时绝对不允许使用[对象.成员名]的格式获取)触发递归!return object.__getattribute__(self,attrname)elif attrname == 'sex':return object.__getattribute__(self,attrname)else:return '对不起,成员不存在或者不允许访问'"""#__setattr__'''触发时机:对成员属性进行设置的时候触发功能:限制或者过滤对象成员的修改参数:一个self接受当前对象 一个接受修改的成员名 一个要修改的成员值返回值:没有返回值!'''def __setattr__(self,attrname,value):#可以载设置成员属性时候进行判断if attrname == 'sex' or attrname == 'name':passelse:object.__setattr__(self,attrname,value)#__delattr__ 魔术方法def __delattr__(self, attrname):#根据删除的内容决定是否允许删除if attrname == 'hobby':passelse:object.__delattr__(self,attrname)#实例化对象
szp = Man()'''
#获取对象的成员属性(getattr魔术方法)
print(szp.height)
print(szp.weight)
print(szp.length)
'''#获取对象的成员属性(getattribute)
#print(szp.color)#设置成员属性
#szp.sex = 'no man no woman'
#print(szp.sex)#szp.name = '失了志'
#print(szp.name)#szp.color = 'black'
#print(szp.color)#删除成员属性
print(szp.__dict__)
del szp.gf
print(szp.__dict__)
5._dir_()
触发时机:dir(对象)的时候触发
参数:1个接收当前对象self
返回值:必须为序列类型(列表,元组,集合等,)
作用:可以自定义成员列表的返回值
#dir魔术方法
class Human:#属性sex = 'man'age = 18name = '家晷'#方法def eat(self):print('吃凉菜')def drink(self):print('喝凉水')#__dir__def __dir__(self):#获取是哦有可以访问的成员lists = object.__dir__(self)#过滤魔术方法 只留下自定义成员newlists = []for i in lists:if i.startswith('__') and i.endswith('__'):passelse:newlists.append(i)return newlists#实例化对象
qw = Human()#获取当前对象中所有存在的成员
result = dir(qw)
print(result)#查看所有内置函数 内置变量'''
#方法一
print(dir(__builtins__))
#方法二
import builtins
print(dir(builtins))
''''''
dir 查看对象或者类的内置属性 方法 魔术方法
dir(对象) 对象的所有内置属性 方法 魔术方法 (包括类的)
dir(类) 类的所有内置属性 方法 魔术方法(只有类的)
'''
运算相关魔术方法(上帝模式)
比较运算相关魔术方法
1._lt_()
格式:def __lt__(self,other):return 数据特征:触发时机:进行小于判断时自动触发参数:2个参数第一个是self,第二个判断的第二个对象返回值:返回值可以任意类型,推荐布尔值作用:定义小于号的行为:x < y 调用 x.lt(y)
2._le_()
格式:def __le__(self):return str特征:触发时机:进行小于等于判断时自动触发参数:2个参数第一个是self,第二个判断的第二个对象返回值:返回值可以任意类型,推荐布尔值作用:定义小于等于号的行为:x <= y 调用 x.le(y)
3._gt_()
格式:def __gt__(self):return str特征:触发时机:进行大于判断时自动触发参数:2个参数第一个是self,第二个判断的第二个对象返回值:返回值可以任意类型,推荐布尔值作用:定义大于号的行为:x > y 调用 x.gt(y)
4._ge_()
格式:def __ge__(self):return str特征:触发时机:进行大于等于判断时自动触发参数:2个参数第一个是self,第二个判断的第二个对象返回值:返回值可以任意类型,推荐布尔值作用:定义大于等于号的行为:x >= y 调用 x.ge(y)
5._eq_()
格式:def __eq__(self):return str特征:触发时机:进行等于判断时自动触发参数:2个参数第一个是self,第二个判断的第二个对象返回值:返回值可以任意类型,推荐布尔值作用:定义大于等于号的行为:x == y 调用 x.eq(y)
6._ne_()
格式:def __ne__(self):return str特征:触发时机:进行不等于判断时自动触发参数:2个参数第一个是self,第二个判断的第二个对象返回值:返回值可以任意类型,推荐布尔值作用:定义不等号的行为:x != y 调用 x.ne(y)
#比较运算class Myint(int):#__eq__ 相等魔术方法def __eq__(self,other):#print('eq方法被触发')#print(self,other)#自定义规则:如果2歌数都能被6整除 相等 其余都不想等if self % 6 == 0 and other % 6 == 0:return Trueelse:return False#__gt__ 大于比较魔术方法def __gt__(self,other):#print('gt方法被触发')#print(self,other)if self % 5 > other % 5:return Trueelse:return False#实例化对象
no1 = Myint(24)
no2 = Myint(92)#相等运算
#result = no1 == no2
#print(result)#练习:只要各位数相等 就相等,其余都不想等#大于运算
result = no1 > no2
print(result)
算术运算相关魔术方法
__add__(self, other) 定义加法的行为:+
__sub__(self, other) 定义减法的行为:-
__mul__(self, other) 定义乘法的行为:
__truediv__(self, other) 定义真除法的行为:/
__floordiv__(self, other) 定义整数除法的行为://
__mod__(self, other) 定义取模算法的行为:%
__divmod__(self, other) 定义当被 divmod() 调用时的行为
__pow__(self, other[, modulo]) 定义当被 power() 调用或 ** 运算时的行为
__lshift__(self, other) 定义按位左移位的行为:<<
__rshift__(self, other) 定义按位右移位的行为:>>
__and__(self, other) 定义按位与操作的行为:&
__xor__(self, other) 定义按位异或操作的行为:^
__or__(self, other) 定义按位或操作的行为:|
反运算相关魔术方法
__radd__(self, other) 与上方相同,当左操作数不支持相应的操作时被调用
__rsub__(self, other) 与上方相同,当左操作数不支持相应的操作时被调用
__rmul__(self, other) 与上方相同,当左操作数不支持相应的操作时被调用
__rtruediv__(self, other) 与上方相同,当左操作数不支持相应的操作时被调用
__rfloordiv__(self, other) 与上方相同,当左操作数不支持相应的操作时被调用
__rmod__(self, other) 与上方相同,当左操作数不支持相应的操作时被调用
__rdivmod__(self, other) 与上方相同,当左操作数不支持相应的操作时被调用
__rpow__(self, other) 与上方相同,当左操作数不支持相应的操作时被调用
__rlshift__(self, other) 与上方相同,当左操作数不支持相应的操作时被调用
__rrshift__(self, other) 与上方相同,当左操作数不支持相应的操作时被调用
__rand__(self, other) 与上方相同,当左操作数不支持相应的操作时被调用
__rxor__(self, other) 与上方相同,当左操作数不支持相应的操作时被调用
__ror__(self, other) 与上方相同,当左操作数不支持相应的操作时被调用
#其他魔术方法#自定义我们自己的整型类
class Myint(int):#__add__加法的魔术方法(int类中本来就有)def __add__(self,other):#print('add方法被触发')#print(self,other)return int(self) - int(other)#__radd__反向加法的魔术方法(int类中本来就有)# def __radd__(self,other):# #print('radd方法被触发')# print(self,other)# return int(self) * int(other)#实例化对象
no1 = Myint(50)
#print(no1,type(Myint))'''
#正向加法运算 __add__
result = no1 + 15
print(result)#练习:自定义一个整型,相加时进行的运算为10位数相乘+个位数相减
'''#反向加法运算 __radd__
result = 40 + no1
print(result)#练习:自定义一个整型,反向相加运算时获取2个数值的各位数的乘积作为结果
赋值运算相关魔术方法
__iadd__(self, other) 定义赋值加法的行为:+=
__isub__(self, other) 定义赋值减法的行为:-=
__imul__(self, other) 定义赋值乘法的行为:=
__itruediv__(self, other) 定义赋值真除法的行为:/=
__ifloordiv__(self, other) 定义赋值整数除法的行为://=
__imod__(self, other) 定义赋值取模算法的行为:%=
__ipow__(self, other[, modulo]) 定义赋值幂运算的行为:**=
__ilshift__(self, other) 定义赋值按位左移位的行为:<<=
__irshift__(self, other) 定义赋值按位右移位的行为:>>=
__iand__(self, other) 定义赋值按位与操作的行为:&=
__ixor__(self, other) 定义赋值按位异或操作的行为:^=
__ior__(self, other) 定义赋值按位或操作的行为:|=
一元运算相关魔术方法
__pos__(self) 定义正号的行为:+x
__neg__(self) 定义负号的行为:-x
__abs__(self) 定义当被 abs() 调用时的行为
__invert__(self) 定义按位求反的行为:~x
类型转换相关魔术方法 JIANG
__complex__(self) 定义当被 complex() 调用时的行为(需要返回恰当的值)
__int__(self) 定义当被 int() 调用时的行为(需要返回恰当的值)
__float__(self) 定义当被 float() 调用时的行为(需要返回恰当的值)
__round__(self[, n]) 定义当被 round() 调用时的行为(需要返回恰当的值)
__index(self)__ 1. 当对象是被应用在切片表达式中时,实现整形强制转换2. 如果你定义了一个可能在切片时用到的定制的数值型,你应该定义 index3. 如果 index 被定义,则 int 也需要被定义,且返回相同的值
上下文管理相关魔术方法
_enter_() 和 _exit_()
enter(self)1. 定义当使用 with 语句时的初始化行为2. enter 的返回值被 with 语句的目标或者 as 后的名字绑定exit(self, exctype, excvalue, traceback)1. 定义当一个代码块被执行或者终止后上下文管理器应该做什么2. 一般被用来处理异常,清除工作或者做一些代码块执行完毕之后的日常工作
容器类型相关魔术方法
__len__(self) 定义当被 len() 调用时的行为(返回容器中元素的个数)
__getitem__(self, key) 定义获取容器中指定元素的行为,相当于 self[key]
__setitem__(self, key, value) 定义设置容器中指定元素的行为,相当于 self[key] = value
__delitem__(self, key) 定义删除容器中指定元素的行为,相当于 del self[key]
__iter__(self) 定义当迭代容器中的元素的行为
__reversed__(self) 定义当被 reversed() 调用时的行为
__contains__(self, item) 定义当使用成员测试运算符(in 或 not in)时的行为
类的常用函数
issubclass()
检测一个类是否是另外一个类的子类格式1:issubclass(被检测类,父类)
返回值:布尔值格式1:issubclass(被检测类,(父类1,父类2,父类3...))
返回值:布尔值注意:只要有一个类是当前被检测类的父类,那么最终结果就是True
isinstance()
检测一个对象是否是某个类的对象格式1:isinstance(对象,类)
返回值:布尔值格式2:isinstance(对象,(类1,类2,类3...))
返回值:布尔值注意:只要一个类是当前对象的类,那么最终结果就是True
hasattr()
检测对象/类是否具有某个成员格式:hasattr(对象/类,'成员名')
返回值:布尔值
getattr()
获取对象/类中的成员值格式:getattr(对象,'成员名'[,成员不存在时的默认值])
返回值:成员的值
setattr()
设置或者添加对象/类中的成员格式:setattr(对象,'成员名',值)
返回值:None
delattr()
删除对象/类中的成员格式: delattr(对象,成员)
返回值:None
dir()
获取对象的成员名称列表格式:dir(对象)
返回值:列表
property()
用于设置成员属性的修饰符格式:成员属性 = property(获取的方法,设置的方法,删除的方法)
#issubclass() 检测一个类是否是另外一个或者一组类中的子类class Father:passclass Mother:passclass LaoWang:passclass Son(Father,Mother):pass#检测
#result = issubclass(Son,Father)
#result = issubclass(Son,Mother)
#result = issubclass(Son,LaoWang)
result = issubclass(Son,(LaoWang,Mother))#检测是否是Mother或者Laowang的子类
print(result)#isinstance() 检测某个对象是否是制定类的对象(类型检测)
a = 10
#result = isinstance(a,int)
#result = isinstance(a,float)
result = isinstance(a,(Father,int)) #检测a是否是Father或者int类的对象
print(result)#hasattr() 检测类和对象是否有制定的成员class Human:#属性sex = 'man'age = 19color = 'yellow'#方法def __init__(self):self.hair = '黑色'def eat(self):print('吃饭饭!')wbq = Human()#result = hasattr(wbq,'sex')
#result = hasattr(wbq,'age')
result = hasattr(wbq,'drink')
print(result)result = hasattr(Human,'sex')
print(result)#getattr() 获取对象/类成员的值
#已存在
#result = getattr(wbq,'age') # 相当于wbq.age
#不存在
result = getattr(wbq,'weight','90kg')#成员不存在时设置获取的默认值
print(result)#setattr() 设置对象/类成员的值
print(wbq.age)
setattr(wbq,'age',29)#相当于wbq.age = 29
print(wbq.age)#delattr() 删除对象/类成员的值 如果设置了就是对象的值 哪怕和类内名字一样
print(wbq.hair)
delattr(wbq,'hair')
print(wbq.hair)
描述符
python中的描述符是用于描述对象中的属性。主要作用就是对属性操作提供限制,验证,管理等相关权限的操作。
描述符主要有三种操作需要设置:
get 获取属性的操作set 设置属性的操作delete 删除属性的操作
描述符方法1
#描述符类
class Description:#成员属性#name = ''#初始化方法def __init__(self):#为当前类/对象添加一个成员属性(当前类)来接收需要描述的成员属性(要描述的类)此处还没有接收(占位)self.name = None#get获取属性值的方法def __get__(self,obj,cls):# self 用于接收当前描述符类的对象 obj 接收用于管理的成员的对象 cls 用于接收管理成员的类print('获取方法被触发')self.name = str(self.name)return self.name[:4]#set设置属性值的方法def __set__(self,obj,val): #self 用于接收当前描述符类的对象 obj 接收用于管理的成员的对象 val 设置的值print('设置方法被触发')#print(self,obj,val)#在此处可以添加限制和判断(密码奇数时*2)if val %2 == 1:val *= 2#完成了(email)对象的属性值的设置self.name = val#delete删除属性值的方法def __delete__(self,obj): #self当前描述符类的对象 obj 接收用于管理的成员的对象#用户代为删除操作del self.name#声明一个邮箱的类
class Email#属性#用户名account = 'conghao@zhiling.com'#密码(为密码设置了描述符 的对象) 这一步相当于吧password的所有传入了Description的对象当中password = Description()
描述符方法2:
#邮箱类
class Email:#成员属性#为username添加描述符#username = ''#设置邮箱账号最大的长度maxlength = 6#为描述符添加一个临时变量(在描述符中代替username进行操作)tmpusername = None password = ''#成员方法#为username的描述符进行设置(添加方法)#获取username的描述符方法def getusername(self):print('获取操作被触发')#返回值之前进行值的修饰,两边添加星星if self.tmpusername != None:self.tmpusername = '★' + self.tmpusername + '★'#设置获取username的时候的值return self.tmpusername#设置username的描述符方法def setusername(self,val):print('设置操作被触发')#限制,根据Email类的最大账号长度对用户名进行截取之后在设置#检测val是否是字符串类型if isinstance(val,str):val = val[0:self.maxlength]self.tmpusername = val#删除username的描述符方法def delusername(self):print('删除操作被触发')#删除操作del self.tmpusername#为username设置描述符username = property(getusername,setusername,delusername)
3.属性修饰符
#邮箱类
class Email:#用户名username = ''#密码password = ''#使用描述符来操作昵称#昵称petname = '小乖乖'#为描述符设置临时变量__petname = None#成员方法(暂无)#描述符设置的三个部分 获取,设置和删除#处理petname获取操作@propertydef petname(self):print('获取操作被触发')return self.__petname#处理petname的设置操作@petname.setterdef petname(self,val):print('设置操作被触发')#设置操作self.__petname = val#处理petname的删除操作@petname.deleterdef petname(self):print('删除操作被触发')#删除操作del self.__petname
类的内置属性
_dict_
获取当前类/对象成员组成的字典
_doc_
获取当前类/对象的文档,和函数一样使用''' 定义即可
_name_
类.__name__是获取当前类名,如果直接写__name__则是获取模块的名称
_bases_
获取类的继承列表中所有父类组成的元组
#类和对象常用的属性class Animal:pass
class Demo:passclass Human(Animal,Demo):'''这是类的文档,一个人类的类介绍:成员:方法:'''#属性sex = 'man'age = 18color = 'yellow'#方法def sleep(self):print('睡觉觉')def hit(self):print('打豆豆')dd =Human()#__dict__ 获取对象或者类的自身成员
print(Human.__dict__)
print(dd.__dict__)
#__doc__ 获取类的文档
print(Human.__doc__)
print(dd.__doc__)#__name__获取类名 (类来使用对象不行)
print(Human.__name__)#__bases__ 获取一个类直接继承的所有父类元祖
print(Human.__bases__)#__moudle__ 获取类的模块名称 __main__ 当前类文件直接执行的文件
print(Human.__module__)
装饰器
装饰器就是对函数或者方法或者类进行修饰
'''
#第一步:创建一个普通函数
def laxi():print('噗哧噗哧噗哧噗哧~~~')#调用函数
laxi()
laxi()
''''''
#第二步:扩展函数的功能(不是装饰器)
#声明一个扩展函数
def decor(func):print('求神拜佛,祝愿一切顺利')func()#相当于调用laxi()print('拉稀成功,烧香还愿')
def laxi():print('噗哧噗哧噗哧噗哧~~~')
#将laxi函数传入decor函数中
laxi = decor(laxi)
#调用函数
laxi()
laxi()
''''''
#第三步:扩展函数的功能(不是装饰器),使用语法糖
#声明一个扩展函数
def decor(func):print('求神拜佛,祝愿一切顺利')func()#相当于调用laxi()print('拉稀成功,烧香还愿')
@decor #将laxi函数传入decor函数中#laxi = decor(laxi)
def laxi():print('噗哧噗哧噗哧噗哧~~~')
#调用函数
laxi()
laxi()
''''''
#第四步:实现基本的装饰器
def decor(func):#函数名随便写#声明内部函数来制作完整的装饰函数def _decor():#函数名随便写print('求神拜佛,祝愿一切顺利')func()#相当于调用laxi()print('拉稀成功,烧香还愿')return _decor
@decor#laxi = decor(laxi)
def laxi():print('噗哧噗哧噗哧噗哧~~~')
#调用函数
laxi()
laxi()
laxi()
laxi()
''''''
#第五步:实现带有参数和返回值的哦装饰器
#装饰器
def decor(func):#这就是未来的拉稀函数def _decor():print('求神拜佛,祝愿一切顺利')#调用拉稀函数时接收拉稀函数本身的返回值result = func()#相当于调用laxi()print('拉稀成功,烧香还愿')#为装饰之后的函数返回一个值return result#返回内部函数作为未来的laxi函数return _decor
@decor
#拉稀函数
def laxi():print('噗哧噗哧噗哧噗哧~~~')return '热翔一碗'
#调用拉稀函数
jg = laxi()
print(jg)
''''''
#装饰器
def decor(func):#这就是未来的拉稀函数(原函数有什么形参,这里就要有什么形参)def _decor(who,weight):print('求神拜佛,祝愿一切顺利')#调用拉稀函数时接收拉稀函数本身的返回值result = func(who,weight)#相当于调用laxi()print('拉稀成功,烧香还愿')#为装饰之后的函数返回一个值return result#返回内部函数作为未来的laxi函数return _decor
@decor
#拉稀函数
def laxi(who,weight):print('噗哧噗哧噗哧噗哧~~~:'+who+'拉了'+weight+'斤便便')return '热翔一碗'
jg = laxi('马俊龙','10')
print(jg)
''''''
#第六步:收集参数装饰器(给装饰器内部的函数加参数)
def decor(func):#返回未来的拉稀函数def _decor(*who,*weight):print('求神拜佛,祝愿一切顺利')result = func(*who,**weight)print('拉稀成功,烧香还愿')return result#返回装饰之后的函数return _decor
@decor
def laxi(*who,**weight):print('噗哧噗哧噗哧噗哧~~~')print('参与拉屎的人有:',who)print('分别拉了多少:',weight)return '热翔一大锅!'
#调用函数
jg = laxi('马俊龙','阎瑞龙','霍云瑞','曹睿','宋笑寒',mjl = '5斤',yrl = '2斤',hyr= '1吨',cr = '10克',sxh = '便秘')
print(jg)
''''''
#第七步:带有参数的装饰器(给装饰器加参数)
#定义装饰器(接收装饰器参数)
def decor(arg):#接收函数的参数def _decor(func):#未来的拉稀和吃饭函数的装饰def __decorla():#未来的拉稀函数print('求神拜佛,祝愿一切顺利')result = func()print('拉稀成功,烧香还愿')return resultdef __decorchi():#未来的吃饭函数print('我要开动了~')result = func()print('我吃完了~')return result#根据装饰器的参数返回不同的装饰结果if arg == 'la':return __decorlaelif arg == 'chi':return __decorchi#返回装饰器的第一层return _decor
@decor('la')
def laxi():print('噗哧噗哧噗哧噗哧~~~')return '热翔一碗'
@decor('chi')
def chifan():print('吧唧吧唧吧唧吧唧!~~~')return '空碗一个'
#调用laxi
jg = laxi()
print(jg)
#调用chifan
jg = chifan()
print(jg)
''''''
#第八步:将类作为装饰器参数传入进来
#祝愿祈福类
class Wish:#绑定类的方法def before():print('烧香拜服,祝愿一切顺利!')#绑定类的方法def after():print('拉稀成功,烧香还愿~')
#装饰器
def decor(cls):def _decor(func):#这是未来的拉稀函数def __decor():cls.before()result = func()cls.after()return result#返回装饰之后的函数return __decorreturn _decor
@decor(Wish)
def laxi():print('噗哧噗哧噗哧噗哧~~~')return '热翔一手'
#调用函数
jg = laxi()
print(jg)
''''''
#第九步:将类作为装饰器使用
class Decor:def __init__(self,arg):#存入对象self.arg = arg#此魔术方法用于接收原函数def __call__(self,func):#将原方法存到对象当中self.func = func#返回装饰之后的函数return self.mylaxi#装饰函数def mylaxi(self):print('烧香拜服,祝愿一切顺利!')#调用原函数result = self.func()print('拉稀成功,烧香还愿~')return result
@Decor(5)
def laxi():print('噗哧噗哧噗哧噗哧~~~')return '热翔一手'
jg = laxi()
print(jg)
''''''
#第十步:为类添加装饰器(单例模式)
#声明一个容器用于存放对象
obj = {}#假设存入的对象键名only 值为对象本身 {'only':对象}
def decor(cls):#装饰器的操作def _decor():if 'only' in obj:#对象已经创建return obj['only']else:#对象没有创建,创建对象并返回obj['only'] = cls()return obj['only']#返回装饰的操作return _decor
#当前类只能实例化一个对象
@decor
class LiXue:name = '小雪'sex = '女'age = '21岁'def stuPy():print('好好学习天天向上!')
#实例化第一个对象
one = LiXue()
print(one)
two = LiXue()
print(two)
three = LiXue()
print(three)
'''
#第十一步:多个装饰器嵌套
#装饰器1
def decor1(func):def _decor1():print('脱裤子,准备放炮')result = func()print('拉屎完毕,提裤子走人~')return resultreturn _decor1
#装饰器2
def decor2(func):def _decor2():print('烧香拜佛,祝愿一切顺利!')result = func()print('操作成功,烧香还愿')return resultreturn _decor2
@decor2
@decor1
def laxi():print('扑哧扑哧扑哧扑哧扑哧~~')return '热翔一大杯'
jg = laxi()
print(jg)
方法的分类
类和对象的方法一共分为三种:
实例方法/对象方法
只有实例化对象之后才可以使用的方法,该方法的第一个形参接收的一定是对象本身!
绑定类的方法/静态方法
无需实例化,可以通过类直接调用的方法,方法中的参数既不接收对象名也不接受类。 一般方法可以独立调用,跟类中其他成员关联不大
类方法
无需实例化,可以通过类直接调用的方法
但是方法的第一个参数接收的一定是类本身,这种方法一般情况下需要借助类中其他成员操作
#包含各种方法的类
class Person:#绑定类的方法,静态方法@staticmethod #可以省略不写def walk():print('走路方法,绑定类的方法')#非绑定类的方法 对象方法def say(self):print(self)print('说话功能,非绑定类方法')#类方法@classmethod #必须写def drink(cls):print(cls)print('喝水方法,类方法')#调用非绑定类的方法(对象/实例方法)
tw = Person()
tw.say()#绑定类的方法,静态方法
Person.walk()#调用类方法
Person.drink()
class Cat:color = "orange"age = 2sex = "gong"def getFish(self):print(self)print('在抓鱼')def cry():print("miao")@classmethoddef run(cls):print(cls)print("跑步")#静态方法@staticmethoddef jump():print('跳跳跳')#实例化对象
mimi = Cat()#对象方法mimi.getFish()
Cat.cry()Cat.run()Cat.jump()
mimi.jump()
抽象类
具有抽象方法的类就是抽象类。
抽象方法就是没有完成的方法。只有方法名称和参数,没有方法内容的方法。
作用:适合于领导指定开发规范及多人协作完成类。
abc abstract class 抽象类的缩写
抽象类的语法
#使用抽象类必须使用abc模块
import abc#书写抽象类必须指定抽象类的元类 固定格式
class Human(metaclass = abc.ABCMeta):age = 10sex = "mu"color = "black"#定义一个抽象的实例方法/非绑定类的方法@abc.abstractmethoddef smoking(self):pass#定义一个抽象的类方法@abc.abstractclassmethoddef say(cls):pass#定义一个抽象的静态方法/绑定类的方法@abc.abstractstaticmethod def cry():pass
import abc
class User(metaclass=abc.ABCMeta):#属性username =''userid = 0#方法#添加@abc.abstractmethoddef add(self,name,pwd):pass#删除@abc.abstractclassmethoddef dell(cls,uid):pass#修改@abc.abstractstaticmethoddef modd():pass#查找def find(self):print("find")class MUser(User):def add(self,name,pwd):print("添加")class YUser(MUser):@classmethoddef dell(cls,uid):print("删除")class SUser(YUser):@staticmethoddef modd():print("修改")user = SUser()user.add("123","12")SUser.dell("12")user.modd()user.find()
抽象类的特征:
1.抽象类中可以包含具体的方法也可以包含抽象方法
2.抽象类中可以包含成员属性,而且属性没有抽象不抽象之分
3.抽象类无法实例化使用.
4.抽象类只能被其他类继承使用,(唯一的用法)
5.只有子类实现了抽象类的所有抽象方法之后,该子类才可以正常实例化使用。有一个抽象方法没有实现都不可以实例化
6.抽象类的作用是指定程序开发的标准(方法名,参数等)
多态
多态,多种状态!就是一个类,根据不同的情况,相同的方法产生不同的结果。
import abcclass Animal:@abc.abstractmethoddef niao(self):pass@abc.abstractmethoddef la(self):pass@abc.abstractmethoddef jiao(self):passclass Dog(Animal):def niao(self):print("抬起后腿尿")def la(self):print("蹲着拉")def jiao(self):print("汪汪叫")class Cat(Animal):def niao(self):print("蹲着尿")def la(self):print("蹲着拉")def jiao(self):print("喵喵叫")class Chick(Animal):def niao(self):print("站着尿")def la(self):print("站着拉")def jiao(self):print("打野老万")class Action:def __init__(self,animal):self.animal = animaldef niao(self):self.animal.niao()def la(self):self.animal.la()def jiao(self):self.animal.jiao()xiaohei = Dog()
miao = Cat()
hua = Chick()a = Action(xiaohei)a.jiao()