"""
与类相关的魔术方法
0. __init__ # 实例化时触发,为对象添加成员,参数self,无返回值
0. __new__ # 实例化时触发,在__init__之前,控制对象的创建过程,参数cls,返回值为对象或None
1. __del__ # 对象被内存回收时触发,用于对象使用完毕后的资源回收,参数self,无返回值
2. __str__ # 使用print(对象)或str(对象)时触发,用于查看对象,参数self,必须返回字符串类型
3. __repr__ # 使用repr(对象)时触发,功能与__str__一致
4. __call__ # 把对象当做函数调用时触发,用于模拟函数化操作,参数self,返回值看需求
5. __bool__ # 使用bool(对象)时触发,用于强转对象,参数self,返回值必须是bool类型
6. __complex__ # 使用complex(对象)时触发,用于强转对象,参数self,返回值必须是complex类型
7. __int__ # 使用int(对象)时触发,用于强转对象,参数self,返回值必须是int类型
8. __float__ # 使用float(对象)时触发,用于强转对象,参数self,返回值必须是float类型
9. __add__ # 使用对象进行运算相加的时候自动触发,用于对象运算,参数是2个对象,返回值是运算后的值
10.__sub__ # 使用对象进行运算相减的时候自动触发,用于对象运算,参数是2个对象,返回值是运算后的值
11.__mul__ # 使用对象进行运算相乘的时候自动触发,用于对象运算,参数是2个对象,返回值是运算后的值
12.__truediv__ # 使用对象进行运算相除的时候自动触发,用于对象运算,参数是2个对象,返回值是运算后的值
13.__len__ # 使用len(对象)时触发,用于检测对象中或者类中成员的个数,参数self,返回值必须是整型
14.__iter__ # 定义迭代容器中的元素的行为
15.__reversed__ # 定义当被reversed()调用时的行为
16.__contains__ # 定义当使用成员测试运算符(in 或 not in)时的行为
"""
"""
与类相关的魔术属性
1. __dict__ # 获取对象或类的内部成员结构
2. __doc__ # 获取对象或类的内部文档
3. __name__ # 获取类名函数名
4. __class__ # 获取当前对象所属的类
5. __bases__ # 获取一个类直接继承的所有父类,返回元组
"""
class LangDog():
food = "吃肉"
def __init__(self, name):
self.name = name
def __del__(self):
print("析构方法被触发")
obj = LangDog("刀疤")
print(obj.name)
o_obj = obj
print(o_obj is obj)
del obj
print(1)
del o_obj
"""当一个值,没有任何变量指向或者引用时,这个值才会真正的被释放.关键字是团灭"""
print(2)
import os
class ReadFile():
def __new__(cls, filename):
if os.path.exists(filename):
return object.__new__(cls)
else:
return print("该文件是不存在的")
def __init__(self, filename):
self.fp = open(filename, mode="r", encoding="utf-8")
def readcontent(self):
content = self.fp.read()
return content
def __del__(self):
self.fp.close()
obj = ReadFile("ceshi.txt")
res = obj.readcontent()
print(res)
"""
__str__ : 使用print(对象)或str(对象)时触发,用来查看对象,参数要有一个self接收当前对象,必须返回字符串类型
# ------------------------------------------------------------
__repr__ : 使用方法与str一致,但平时还是str用的多
"""
class Cat():
gift = "卖萌爬树"
def __init__(self,name):
self.name = name
def __str__(self):
return self.cat_info()
def cat_info(self):
return "{}天生会{}".format(self.name,self.gift)
tom = Cat("tom")
print(tom)
res = str(tom)
print(res)
class Mouse():
gift = "打洞"
def __init__(self,name):
self.name = name
def __repr__(self):
return self.mouse_info()
def mouse_info(self):
return "{}天生就会{}".format(self.name,self.gift)
obj = Mouse("jieri")
res = repr(obj)
print(res)
"""
注意点:
1.不管是str 还是 repr,都是在str或repr强转obj对象时触发,因为强转,所以输出的肯定是字符串
2.在系统底层,如果定义了repr,将会默认赋值给str方法,而反之则不成立
__str__ = __repr__ 将右侧赋值给左侧
3.底层存在赋值调用给str的语法,所以能实现打印或者str强转对象的触发机制.
"""
"""
__call__ : 把对象当做函数调用的时候触发,用于模拟函数化操作,参数self,返回值看需求
"""
class MyClass():
a = 1
def __call__(self, *args, **kwargs):
print("call方法被触发")
obj = MyClass()
obj()
class Wash():
def __call__(self, *args, **kwargs):
self.step1(*args)
self.step2()
self.step3()
def step1(self,*args):
print("洗{}".format(*args))
def step2(self):
print("剪")
def step3(self):
print("吹")
obj = Wash()
obj("刷刷")
import math
class MyInt():
def mycalc(self,num,sign=1):
strvar = num.lstrip("0")
if strvar == "":
return 0
return eval(strvar) * sign
def __call__(self, num):
if isinstance(num,bool):
if num == True:
return 1
else:
return 0
elif isinstance(num,int):
return num
elif isinstance(num,float):
return math.floor(num) if num >= 0 else math.ceil(num)
elif isinstance(num,str):
if (num[0] == "+" or num[0] == "-") and num[1:].isdecimal():
if num[0] == "+":
sign = 1
else:
sign = -1
return self.mycalc(num[1:],sign)
elif num.isdecimal():
return self.mycalc(num)
else:
return "做不到"
myint = MyInt()
print(myint(3.3))
print( myint(0) )
print( myint(3.13) )
print( myint("+00000000000000000001003") ,"<==1=>")
print( myint("+abcd") ,"<===>")
print( myint("-0000000000000000000.1003") ,"<==2=>")
print( int("0000000000000000000003") )
print( int("+0000000000000000000003") )
print( myint("+-+-+-+-+-+-1233444") )
"""
__bool__ : 使用bool(对象)的时候自动触发,用于强转对象,参数必须有一个self,返回值必须是bool类型
"""
class MyClass():
def __bool__(self):
return True
obj = MyClass()
res = bool(obj)
print(res)
"""
__add__ : 使用对象进行运算相加的时候触发,用于对象运算,必须有两个对象作为参数,返回值是运算后的值
"""
class MyAdd():
def __init__(self,num):
self.num = num
def __add__(self, other):
return self.num + other
def __radd__(self,other):
return self.num + other*2
a = MyAdd(7)
b = MyAdd(8)
res = a+b
print(res)
"""
a+b 先触发__add__, self接收7,oter接收b,res = 7+b
7+b 再触发__radd__,self接收b,other接收的是7, 故返回 8+7*2 = 22
"""
"""
__len__ : 使用len(对象)时触发,用于检测对象中或者类中成员的个数,参数self,但必须返回整型
"""
class MyClass():
pty1 = 1
pty2 = 2
pyt3 = 3
def func1(self):
pass
def fucn2(self):
pass
def func3(self):
pass
def func4(self):
pass
def __len__(self):
lst = [i for i in MyClass.__dict__ if not (i.startswith("_"))]
return len(lst)
obj = MyClass()
print(len(obj))
class Man():
pass
class Woman():
pass
class Children(Man, Woman):
"""
成员属性: eye
成员方法: skylight moonread __makebaby
完成的功能: 描述小孩天生神力.
"""
eye = "血轮眼"
def skylight(self):
print("一下生,直接使用天照,让世界变得混乱")
def moonread(self, func):
print("一下生,使出了武功绝学,月读,世界都黑暗里~")
print(func.__name__, type(func.__name__))
def __makebaby(self):
print("这一手招数,只能我自己用")
obj = Children()
print(obj.__dict__)
print(Children.__dict__)
print(obj.__doc__)
print(Children.__doc__)
def earth_boom():
print("使出一招地爆天星")
obj.moonread(earth_boom)
obj.moonread(Children)
print(obj.__class__)
print(Children.__bases__)
"""
继承,一个类除了自身的属性方法之外,还获得了另一个类的成员属性和方法,就是继承
继承分为单继承\多继承,菱形继承
python所有的类都默认继承父类object
"""
class Human(object):
hair = "gold"
sex = "male"
def eat(self):
print("eat")
def la(self):
print("la")
def __makebaby(self):
print("make")
class Man(Human):
sex = "female"
def eat(self):
print("eateat")
obj = Man()
print(obj.hair)
obj.eat()
obj.eat()
class Father(object):
face = "cool"
def hobby(self):
print("eat and drink")
class Mather(object):
face = "beautiful"
def hobby(self):
print("shopping")
class Child(Father,Mather):
pass
obj = Child()
print(obj.face)
obj.hobby()
"""super的用法"""
class Father():
face = "cool"
def f_hobby():
print("eat and drink")
class Mather():
face = "beautiful"
def m_hobby(self):
print("shopping")
class Child(Father,Mather):
face = "black"
def skill(self):
print(Mather.face)
Father.f_hobby()
print(Father.face)
def skill1(self):
self.m_hobby()
print(self.face)
"""
super()调用父类的属性和方法
看下面的例子,super()调用了face这个成员属性,其实这个属性他本来也有,但是并没有调用,而是直接调用了父类的face属性,这说明,super()是不会调用本类成员的,这一点,就是和self最大的不同
self,调用成员属性及方法,优先调用自己,其次调用父类,都没有就报错
"""
def skill2(self):
print(super)
print(super())
print(super().face)
super().m_hobby()
obj = Child()
obj.skill()
obj.skill1()
obj.skill2()
"""
(4 Human 1)
(2 Father 3) (3 Mother 2)
(1 Child 4)
当从C类使用super()时,逐层调用,调用顺序是:去的时候1234,如果后面还有打印的话,回的时候4321
类.mro() 返回的是方法调用顺序的列表,针对于多继承下的同名方法,按照列表顺序依次进行调用
经典类:深度优先
新式类:广度优先
"""
class Human():
num = 4
def feel(self):
print("i am human 1")
print(self.num)
print(obj)
class Man(Human):
num = 3
def feel(self):
print("i am man 3")
super().feel()
class Woman(Human):
num = 2
def feel(self):
print("i am woman 5")
super().feel()
class Child(Man,Woman):
num = 1
def feel(self):
print("i am child 7")
super().feel()
obj = Child()
obj.feel()
lst = Child.mro()
print(lst)
"""
1.issubclass(Child,Man) 判断是否存在子父关系,只要在一个继承链上即可,应用范围:类
2.isinstance(obj,Child) 判断类型,只要在一个继承链上即可,应用范围:对象与类之间
3.in 判断在或者不在, 在True, 不在False
res = "feel" in Child.__dict__
print(res)
"""
"""面向对象oop"""
"""
面向对象的三大特性:封装\继承\多态
封装等级: 1.公有 2.私有
公有成员在类内类外都能调用,私有成员只能在类内调用
所有的调用都是通过: obj.属性 or obj.方法 的语法来实现
类中的绑定方法:
1.绑定到对象 (obj调用方法,系统自动把obj当成self进行传递),绑定方法就是在定义方法的时候加上形参self
2.绑定到类 (obj 或 class调用方法时,系统自动把class当成self进行传递)
"""
class MyCar():
color = "yellow"
__logo = "auto"
def dirve(self):
print("{} car can drive.".format(self.color))
def __info():
print("price are mimi")
obj = MyCar()
print(obj.color)
"""对象调用方法"""
obj.dirve()
print(MyCar.color)
"""实例化对象不能调用私有成员属性及方法"""
"""添加成员的方法"""
def mod1():
print("mod1")
obj.mod1 = mod1
obj.mod1()
def mod2(name):
print("{} is ironman".format(name))
obj.mod2 = mod2
obj.mod2("stack")
def mod3(obj,name):
print("{} is superman, {}".format(name,obj.color))
obj.mod3 = mod3
obj.mod3(obj,"laowang")
import types
def mod4(self,name):
print("hi ,guy {},you are foolish {}".format(name,self.color))
obj.mod4 = types.MethodType(mod4,obj)
obj.mod4("haha")
print(obj)
obj.mod5 = lambda : print(" i am ironman ,too")
obj.mod5()
print(obj.__dict__)
"""此处我们可以看出,obj折腾的这一段,动态添加无参方法\有参方法\lambda,都是基于他自己这个对象建立的,而不是类,类跟对象是占用不同内存空间的,你玩你的,我玩我的,对象可以去调用类的成员属性和方法,但本质上并不能进行修改,对象像是在根据需求"自娱自乐",而类始终没变,私有化有效保证了数据的安全性,而这就是类的三大特性之一--封装"""
"""
1.定义类访问公有成员属性和方法
2.定义类动态添加公有成员属性和方法
类的操作和对象的操作基本一致,需要注意的点是,类中的成员只归属于当前这个类本身,类无法调用对象中的相关成员,对象可以调用类中的相关成员
"""
class Plane():
captain = "魏富强"
__airsistem = 3
def fly(self):
print("飞机会飞,百公里油耗2万升1")
def fly2():
print("飞机会飞,百公里油耗2万升2")
def __plane_info(self):
print("飞机上的空姐数量是保密的,个数%d" % (self.__airsistem))
def __plane_info2():
print("飞机上的空姐数量是保密的,个数%d" % (Plane.__airsistem))
def pub_info(self):
print(self.__airsistem)
self.__plane_info()
def pub_info2():
print(Plane.__airsistem)
Plane.__plane_info2()
obj = Plane()
obj.fly()
Plane.fly2()
print(Plane.__dict__)
print(obj._Plane__airsistem)
print(Plane._Plane__airsistem)
obj._Plane__plane_info()
Plane._Plane__plane_info2()
obj.pub_info()
Plane.pub_info2()
"""
实例化对象删除公有成员和属性\方法
定义的类删除公有成员和属性\方法
都删完,再调用就报错,如果没删干净,那还能调一调
"""
class Plane():
captain = "魏富强"
__airsistem = 3
def fly(self):
print("飞机会飞,百公里油耗2万升1")
def fly2():
print("飞机会飞,百公里油耗2万升2")
def __plane_info(self):
print("飞机上的空姐数量是保密的,个数%d" % (self.__airsistem))
def __plane_info2():
print("飞机上的空姐数量是保密的,个数%d" % (Plane.__airsistem))
def pub_info(self):
print(self.__airsistem)
self.__plane_info()
def pub_info2():
print(Plane.__airsistem)
Plane.__plane_info2()
obj = Plane()
obj.fly()
Plane.fly2()
print(Plane.__dict__)
print(obj._Plane__airsistem)
print(Plane._Plane__airsistem)
obj._Plane__plane_info()
Plane._Plane__plane_info2()
obj.pub_info()
Plane.pub_info2()
obj.captain = "王思聪"
print(obj.__dict__)
del obj.captain
print(obj.__dict__)
print(obj.captain)
obj.func = lambda: print("开飞机是为了泡妞")
obj.func()
del obj.func
del Plane.captain
obj.fly = lambda: print("112233")
del Plane.fly
del obj.fly
"""
构造方法 __init__(self,...)
用于为对象添加成员,在实例化对象时触发,参数至少有一个self,无返回值
"""
class MyClass():
def __init__(self,name):
self.name = name
obj = MyClass("xboy")
print(obj.name)
class Children():
def __init__(self,name,skin):
self.name = name
self.skin = skin
def cry(self):
print("cry")
def drink(self):
print("drink")
def __eat(self):
print("eat")
def pub_func(self):
print("名字{},肤色{}".format(self.name,self.skin))
def pub_func2(self,name,skin):
print("名字{},肤色{}".format(name,skin))
p1 = Children("xboy","green")
p1.cry()
p1.pub_func()
print("<--------->")
p2 = Children("alex","red")
p2.drink()
p2.pub_func()
p2.pub_func2("egon","yellow")
print(p2)
print(p2.__dict__)
print(p1.__dict__)