面向对象都具有三大特性:封装,继承 和 多态
类是多个对象归纳总结而来的,是一种概念,包含所有对象。
由对象总结出类的过程,叫做抽象化
对象是类的具体实现或者实施而来,他是真实的,特指某个事物。
由类制作出对象的过程,叫做实例化
类中只有2种内容:成员属性和成员方法
成员属性:
用于描述类的特征的变量就是成员属性
成员方法:
用于描述类的功能的函数就是成员方法
实例化对象格式
对象变量 = 类()
类的类型为 type
类的值就是类本身
对象的类型为类
对象的值,对象本身
<__main__.Person object at 0x020DC650>
class GirlFriend:
#属性
sex = '女'
age = 18
height = '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__)
他不是关键字,是一个随意书写的字符串而已
1.英文单词的意义 :自己
2.绑定类的方法,只能通过类来访问的方法,就是绑定类的方法
3.非绑定类的方法,就是可以通过对象访问的方法就是非绑定的方法
4.绑定类与非绑定类的方法不取决于语法,而取决于设计者如何设计该方法
5.一般情况下非绑定类的方法第一个参数写单词self,但是这不是唯一的单词,写什么都行,self不是关键字,不是关键字,不是关键字!
class Human:
#属性 -> 成员属性(变量)
ear = 2
mouth = 1
sex = 'man'
age = 28
name = '章旺'
married = False
color = '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 英文单词而不是关键字
检测封装的三个位置:
类中/对象中
类外部/对象外部
子类中
私有化封装是最高级别的封装。私有化封装之后的成员,只能在类中/对象中访问,类的外部,子类中都不可以访问到。
私有化封装:在成员名称前添加2个_即可
例如:封装heart -> __heart
python将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):
#访问私有方法niao
self.__niao()
print('测试私有成员的访问')
受保护的封装是一定级别的封装,封装之后,只有部分位置可以访问(类和子类),部分位置(类外)不可以访问。
受保护的封装: 在成员名称前添加1个_即可
例如:受保护 money -> _money
封装后的访问限制:
类中/对象中 可以访问
类外/对象外 可以访问(原则上类外不行,但是没实现)
子类/子类对象 可以访问
**注意:**受保护的封装依旧是通过name mangling的方式修改了成员的名称而已。
可以通过对象.类名成员 或者类名.类名成员的方式访问(但也别这么干)
#python语法中没有受保护的语法,程序员约定一种操作来实现受保护
class Father:
#属性
sex = 'man'
#受保护的
_money = 1000
color = '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类外部应该不能访问!)
公共的: √ √ √
'''
所有的成员默认都是公共的封装级别,可以在类中,类外,及子类中正常访问
类中/对象中 可以访问
类外/对象外 可以访问
子类/子类对象 可以访问
继承就是可以获取另外一个类中的成员属性和成员方法。(并非所有成员)
**作用:**继承的作用是增加代码的复用性,节省不必要的重复代码,提高开发效率,同时可以设置类之间的关系。
继承的两个概念:
父类
用于被继承的类,称之为父类,也叫做基类,或者超类
子类
继承其他类的类,称之为子类,也叫做派生类
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:
pass
class 父类2:
pass
class 子类(父类1,父类2):
pass
多继承之后,子类就具备了所有父类的成员(私有成员除外)
多个父类具有相同的成员时,子类继承[继承列表]中第一个类的方法
菱形继承格式
class A:
pass
class B(A):
pass
class C(A):
pass
class D(B,C):
pass
A
/ \
B C
\ /
D
菱形继承存在的问题
如果BC类同时继承了A类,D类又继承了BC两个类的情况下(菱形继承),
在调用BC中某个同名方法(该方法都继承自A类)时会导致继承自A类的该方法被多次调用。产生逻辑问题!
所以python使用 super() 类来解决了多继承的菱形继承问题
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
#人类say
super().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()的作用不是查找父类,而是找MRO列表的下一个类
super()和父类没有任何实质性的关系,只是有时候能调用到父类而已。
在单继承的情况下,super()永远调用的是父类/父对象
格式:
super().方法() #python3的格式
多继承按需操作,在没有必要的时候避免强行使用!
该设计模式的主要作用是采用多继承方式,进行类的扩展。
优点:
#水果类
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
魔术方法就是一个类/对象中的方法,和普通方法唯一的不同时,普通方法需要调用!而魔术方法是在特定时刻自动触发。
初始化魔术方法
触发时机:初始化对象时触发(不是实例化触发,但是和实例化在一个操作中)
参数:至少有一个self,接收对象
返回值:无
作用:初始化对象的成员
注意:使用该方式初始化的成员都是直接写入对象当中,类中无法具有
import random
class Human:
#属性
age = 1
color = '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__)
实例化魔术方法
触发时机: 在实例化对时触发
参数:至少一个cls 接收当前类
返回值:必须返回一个对象实例
作用:实例化对象
注意:实例化对象是Object类底层实现,其他类继承了Object的__new__才能够实现实例化对象。
没事别碰这个魔术方法,先触发__new__才会触发__init__
class Human:
#属性
age = 18
sex = 'man'
#方法
def __new__(cls,diyname):
#print('new方法被触发')
print(cls)
return object.__new__(cls)
def __init__(self,diyname):
pass
def sleep(self):
print('教室睡觉真香甜')
def eat(self):
print('吃蛋蛋炒饭!')
#实例化对象
sy = Human('小洋洋') #1.创建对象(new) 2.对对象进行初始化操作(init)
print(sy)
单例设计模式
class WangYingSong:
#属性
color = '黄色'
age = 27
name = '应松'
#声明了一个类成员属性用于保存创建的对象
obj = None
#方法
def __new__(cls):
#检测是否已经制作国对象
if cls.obj == None:#没有做过对象
#实例化对象(存入当前类中)
cls.obj = object.__new__(cls)
return cls.obj
else:#做过对象,直接将类中保存的对象返回
return cls.obj
def study(self):
print('好好学习天天想上!~')
def eat(self):
print('吃肯德基全家捅!')
#实例化对象1
ys1 = WangYingSong()
print(ys1)
#实例化对象2
ys2 = WangYingSong()
print(ys2)
#实例化对象3
ys3 = WangYingSong()
print(ys3)
析构魔术方法
触发时机:当对象没有用(没有任何变量引用)的时候被触发
参数:一个self 结婚搜对象
返回值:无
作用:使用完对象是回收资源
注意:del不一定会触发当前方法,只有当前对象没有任何变量接收时才会触发
class Human:
#属性
money = 1000
sex = 'man'
age = 18
name = '小松松'
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)
调用对象的魔术方法
触发时机:将对象当作函数调用时触发 对象()
参数:至少一个self接收对象,其余根据调用时参数决定
返回值:根据情况而定
作用:可以将复杂的步骤进行合并操作,减少调用的步骤,方便使用
注意:无
#call魔术方法
'''
触发时机:把对象当作函数调用的时候自动触发
功能:简化操作
参数:至少一个self接受当前对象,其他参数根据程序决定
返回值:根据程序决定
'''
class Human:
#属性
sex = 'man'
age = 18
color = '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)
触发时机:使用len(对象) 的时候触发
参数:一个参数self
返回值:必须是一个整型
作用:可以设置为检测对象成员个数,但是也可以进行其他任意操作
注意:返回值必须必须是整数,否则语法报错,另外该要求是格式要求。
#len魔术方法
'''
触发时机:使用len(对象)的时候自动触发
功能:用于检测对象中或者类中某个内容的个数
参数:只有一个self接受当前对象
返回值:必须返回整型
'''
class Human:
#属性
sex = 'man'
age = 18
color = '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)
触发时机:使用print(对象)或者str(对象)的时候触发
参数:一个self接收对象
返回值:必须是字符串类型
作用:print(对象时)进行操作,得到字符串,通常用于快捷操作
注意:无
#str魔术方法
'''
触发时机:使用print打印对象的时候或者str(对象)都可以触发
功能:定义对象转换为字符串的结果
参数:一个self接受对象
返回值:必须返回字符串类型
'''
class Human:
#属性
sex = 'man'
age =18
name = '王成'
#方法
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)
触发时机:在使用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 = 18
height = '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))
触发时机: 使用bool(对象)的时候触发
参数:一个self接收对象
返回值:必须是布尔值
作用:根据实际情况决定,可以作为快捷方式使用
注意:仅适合于返回布尔值的操作
#bool魔术方法
'''
触发时机:使用bool(对象)的时候自动触发
功能:根据某个规则确定对象的布尔值转换结果
参数:一个self接受当前对象
返回值:必须是布尔类型
'''
class Human:
#属性
sex = 'woman'
age = 18
color = 'yellow'
#方法
def getMoney(self):
print('好好学习天天赚钱~')
def sendMoeny(self):
print('随便花')
#__ bool__魔术方法
def __bool__(self):
#print('bool方法被触发')
#设置当前对象 男-》True 女 -》False
if self.sex == 'man':
return True
return False
#实例化对象
bb = Human()
result = bool(bb)
print(result)
触发时机:使用字符串.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描述符对象本身,2描述符描述的属性所在的对象,描述符描述的对象的类
返回值:必须有,不然无法获取相应属性值
注意:仅在描述符中使用
触发时机:在设置或者添加指定描述符操作的成员属性的时候触发
参数:1描述符对象本身,2描述符描述的属性所在的对象,3要设置的值
返回值:无
注意:仅在描述符中使用
触发时机:在删除指定描述符操作的成员属性的时候触发
参数: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.var
else:
pass
class 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)
#描述符2
class 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)
#描述符3
class Email:
#属性
#username = ''
password = ''
#方法
def __init__(self):
#为描述符添加的用于数据通讯的成员属性
self.var = '匿名'
def login(self):
print('登录操作')
def logout(self):
print('退出操作')
#获取操作
@property
def username(self):
result = self.var[0] + '*' + self.var[-1]
return result
#设置操作
@username.setter
def username(self,value):
self.var = value
#删除操作
@username.deleter
def username(self):
del self.var
#实例化对象
e = Email()
#获取用户名
#print(e.username)
#修改用户名
#e.username = '董伟'
#print(e.username)
#删除用户名
del e.username
print(e.username)
触发时机:获取不存在的对象成员时触发
参数:1接收当前对象的self,一个是获取成员名称的字符串
返回值:必须有值
作用:为访问不存在的属性设置值
注意:getattribute无论何时都会在getattr之前触发,触发了getattribute就不会在触发getattr了
触发时机:设置对象成员值的时候触发
参数:1个当前对象的self,一个是要设置的成员名称字符串,一个是要设置的值
返回值:无 过程操作
作用:接管设置操作,可以在设置前之前进行判断验证等行为
注意:在当前方法中无法使用成员=值的方式直接设置成员,否则会无限递归,必须借助object的设置方法来完成
object.__setattr__(参数1,参数2,参数3)
触发时机:删除对象成员时触发
参数:一个当前对象的self
返回值:无
作用:可以在删除成员时进行验证。
触发时机:使用对象成员时触发,无论成员是否存在
参数:1个接收当前对象self,一个是获取的成员的名称字符串
返回值:必须有
作用:在具有封装操作(私有化时),为程序开部分访问权限使用
#与属性相关的魔术方法
class Man:
#属性
sex = 'man'
age = 18
color = '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':
pass
else:
object.__setattr__(self,attrname,value)
#__delattr__ 魔术方法
def __delattr__(self, attrname):
#根据删除的内容决定是否允许删除
if attrname == 'hobby':
pass
else:
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__)
触发时机:dir(对象)的时候触发
参数:1个接收当前对象self
返回值:必须为序列类型(列表,元组,集合等,)
作用:可以自定义成员列表的返回值
#dir魔术方法
class Human:
#属性
sex = 'man'
age = 18
name = '家晷'
#方法
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('__'):
pass
else:
newlists.append(i)
return newlists
#实例化对象
qw = Human()
#获取当前对象中所有存在的成员
result = dir(qw)
print(result)
#查看所有内置函数 内置变量
'''
#方法一
print(dir(__builtins__))
#方法二
import builtins
print(dir(builtins))
'''
'''
dir 查看对象或者类的内置属性 方法 魔术方法
dir(对象) 对象的所有内置属性 方法 魔术方法 (包括类的)
dir(类) 类的所有内置属性 方法 魔术方法(只有类的)
'''
格式:
def __lt__(self,other):
return 数据
特征:
触发时机:进行小于判断时自动触发
参数:2个参数第一个是self,第二个判断的第二个对象
返回值:返回值可以任意类型,推荐布尔值
作用:定义小于号的行为:x < y 调用 x.lt(y)
格式:
def __le__(self):
return str
特征:
触发时机:进行小于等于判断时自动触发
参数:2个参数第一个是self,第二个判断的第二个对象
返回值:返回值可以任意类型,推荐布尔值
作用:定义小于等于号的行为:x <= y 调用 x.le(y)
格式:
def __gt__(self):
return str
特征:
触发时机:进行大于判断时自动触发
参数:2个参数第一个是self,第二个判断的第二个对象
返回值:返回值可以任意类型,推荐布尔值
作用:定义大于号的行为:x > y 调用 x.gt(y)
格式:
def __ge__(self):
return str
特征:
触发时机:进行大于等于判断时自动触发
参数:2个参数第一个是self,第二个判断的第二个对象
返回值:返回值可以任意类型,推荐布尔值
作用:定义大于等于号的行为:x >= y 调用 x.ge(y)
格式:
def __eq__(self):
return str
特征:
触发时机:进行等于判断时自动触发
参数:2个参数第一个是self,第二个判断的第二个对象
返回值:返回值可以任意类型,推荐布尔值
作用:定义大于等于号的行为:x == y 调用 x.eq(y)
格式:
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 True
else:
return False
#__gt__ 大于比较魔术方法
def __gt__(self,other):
#print('gt方法被触发')
#print(self,other)
if self % 5 > other % 5:
return True
else:
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
__complex__(self) 定义当被 complex() 调用时的行为(需要返回恰当的值)
__int__(self) 定义当被 int() 调用时的行为(需要返回恰当的值)
__float__(self) 定义当被 float() 调用时的行为(需要返回恰当的值)
__round__(self[, n]) 定义当被 round() 调用时的行为(需要返回恰当的值)
__index(self)__ 1. 当对象是被应用在切片表达式中时,实现整形强制转换
2. 如果你定义了一个可能在切片时用到的定制的数值型,你应该定义 index
3. 如果 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:
pass
class Mother:
pass
class LaoWang:
pass
class 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 = 19
color = '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 = '[email protected]'
#密码(为密码设置了描述符 的对象) 这一步相当于吧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获取操作
@property
def petname(self):
print('获取操作被触发')
return self.__petname
#处理petname的设置操作
@petname.setter
def petname(self,val):
print('设置操作被触发')
#设置操作
self.__petname = val
#处理petname的删除操作
@petname.deleter
def petname(self):
print('删除操作被触发')
#删除操作
del self.__petname
_dict_
获取当前类/对象成员组成的字典
_doc_
获取当前类/对象的文档,和函数一样使用''' 定义即可
_name_
类.__name__是获取当前类名,如果直接写__name__则是获取模块的名称
_bases_
获取类的继承列表中所有父类组成的元组
#类和对象常用的属性
class Animal:
pass
class Demo:
pass
class Human(Animal,Demo):
'''
这是类的文档,一个人类的类
介绍:
成员:
方法:
'''
#属性
sex = 'man'
age = 18
color = '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 result
def __decorchi():#未来的吃饭函数
print('我要开动了~')
result = func()
print('我吃完了~')
return result
#根据装饰器的参数返回不同的装饰结果
if arg == 'la':
return __decorla
elif 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 __decor
return _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 result
return _decor1
#装饰器2
def decor2(func):
def _decor2():
print('烧香拜佛,祝愿一切顺利!')
result = func()
print('操作成功,烧香还愿')
return result
return _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 = 2
sex = "gong"
def getFish(self):
print(self)
print('在抓鱼')
def cry():
print("miao")
@classmethod
def run(cls):
print(cls)
print("跑步")
#静态方法
@staticmethod
def 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 = 10
sex = "mu"
color = "black"
#定义一个抽象的实例方法/非绑定类的方法
@abc.abstractmethod
def smoking(self):
pass
#定义一个抽象的类方法
@abc.abstractclassmethod
def say(cls):
pass
#定义一个抽象的静态方法/绑定类的方法
@abc.abstractstaticmethod
def cry():
pass
import abc
class User(metaclass=abc.ABCMeta):
#属性
username =''
userid = 0
#方法
#添加
@abc.abstractmethod
def add(self,name,pwd):
pass
#删除
@abc.abstractclassmethod
def dell(cls,uid):
pass
#修改
@abc.abstractstaticmethod
def modd():
pass
#查找
def find(self):
print("find")
class MUser(User):
def add(self,name,pwd):
print("添加")
class YUser(MUser):
@classmethod
def dell(cls,uid):
print("删除")
class SUser(YUser):
@staticmethod
def modd():
print("修改")
user = SUser()
user.add("123","12")
SUser.dell("12")
user.modd()
user.find()
1.抽象类中可以包含具体的方法也可以包含抽象方法
2.抽象类中可以包含成员属性,而且属性没有抽象不抽象之分
3.抽象类无法实例化使用.
4.抽象类只能被其他类继承使用,(唯一的用法)
5.只有子类实现了抽象类的所有抽象方法之后,该子类才可以正常实例化使用。有一个抽象方法没有实现都不可以实例化
6.抽象类的作用是指定程序开发的标准(方法名,参数等)
多态,多种状态!就是一个类,根据不同的情况,相同的方法产生不同的结果。
import abc
class Animal:
@abc.abstractmethod
def niao(self):
pass
@abc.abstractmethod
def la(self):
pass
@abc.abstractmethod
def jiao(self):
pass
class 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 = animal
def 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()