文章目录
魔术方法(特定时机自动触发)
__init__
(构造方法)
- 触发时机:实例化对象,初始化的时候触发
- 功能:为对象添加成员,用来初始化的
- 参数:参数不固定,至少一个self参数
- 返回值:无
- 基本用法
class MyClass():
def __init__(self):
# print(1111)
self.name = "张国成"
# 实例化对象 [类的实例化]
obj = MyClass()
print(obj.name)
- __init__ 可以传递多个参数
class MyClass():
def __init__(self,name):
# self.name 这个name 是成员属性name
# self.name = name 后面的name 是传进来的参数
self.name = name
# 类的实例化 实例化对象
# 把参数传递到MyClass后面的这个括号里
obj = MyClass("陈广耀")
print(obj.name)
- 综合案例
类可以是一个,但对象可以是多个.对象之间彼此独立
class Children():
def __init__(self,name,skin):
self.name = name
self.skin = skin
def eat(self):
print("小孩生下来的时候,手里拿了大串大腰子")
def drink(self):
print("小孩生下来,手里拿了两瓶啤酒")
def beat_doudou(self):
print("小孩生下来就喜欢打豆豆")
def obj_info(self):
print("小孩的姓名:{},小孩的肤色是{}".format(self.name,self.skin))
'''
同一个类产生了三个对象,但是每个对象彼此都是独立的
而且都可以调用类中的公有成员属性方法.
'''
child1 = Children("方贵权","黑色的")
child1.obj_info()
child1.eat()
child2 = Children("张国成","屎黄色")
child2.obj_info()
child2.drink()
child3 = Children("王宝强","绿色的")
child3.obj_info()
child3.beat_doudou()
__new__
魔术方法
- 触发时机:实例化类生成对象的时候触发(触发时机在__init__之前)
- 功能:控制对象的创建过程
- 参数:至少一个cls接受当前的类,其他根据情况决定
- 返回值:通常返回对象或None
-
基本用法
python3.x 新式类 python2.x 旧式类, 新式类不需要每次都写一次object,默认继承
作用:控制创建的对象,
class MyClass2():
abc = 1
obj2 = MyClass2()
class MyClass(object):
def __new__(cls):
print(cls) # <class '__main__.MyClass'>
# 借助object父类方法里面__new__ 来为本类创建一个对象
# return object.__new__(cls) # 返回一个本类对象
# return None # 返回一个空对象
# return obj2 # 返回的是一个其他类的对象
pass
# 实例化对象obj
# obj = MyClass()
# print(obj)
# print(obj.abc)
-
对比 __new__ 和 __init__ 的触发时机
__new__ 魔术方法是用来创建对象的
__init__魔术方法是用来初始化对象的
得先有对象,才能够初始化,没有对象初始化谁?
__new__ 的触发时机要快于__init____new__ __init__ 这两个方法的参数要一一匹配.
# (1) 一个参数
class Boat():
def __new__(cls, name):
print(1)
return object.__new__(cls)
def __init__(self, name):
self.name = name
obj = Boat("大锤")
# (2) 无限个参数
class Boat():
def __new__(cls, *args, **kwargs):
print(1)
return object.__new__(cls)
def __init__(self, *args, **kwargs):
strvar = ""
for i in args:
strvar += i + " "
print("小船的贡献者有:", strvar)
print("小船的名字是{}".format(kwargs['name']))
obj = Boat("王俊文", "舒畅", "境泽年", "五金玲", name="Anglelababy")
- 如果通过__new__返回的是其他类的对象,不会触发自己本类的__init__
‘’‘因为__init__初始化的是本类对象’’’
class Boat():
def __new__(cls, *args, **kwargs):
return obj2
def __init__(self):
print("init调用了")
obj = Boat()
print(obj.abc)
__del__
(析构方法)
- 触发时机:当对象被内存回收的时候自动触发[1.页面执行完毕回收所有变量 2.所有对象被del的时候]
- 功能:对象使用完毕后资源回收
- 参数:一个self接受对象
- 返回值:无
import os
class LangDog():
def __init__(self, name):
self.name = name
def eat(self, something):
print("可爱的小狼{},喜欢吃{}".format(self.name, something))
def __del__(self):
print("__del__方法被触发")
- 页面执行完毕回收所有变量
obj = LangDog("詹姆斯·狗蛋")
obj.eat("屎")
print("<===>")
-
所有对象被del的时候
只有当所有指向该对象的变量都删除的时候,才算真正的删除该对象
obj2 = obj
print("<==start===>")
del obj
del obj2
print("<==end===>")
- 用类来模拟文件写的操作
fp = open("ceshi111.txt",mode="w",encoding="utf-8")
fp.write("sfdsdf")
fp.close()
fp = open("ceshi111.txt",mode="r",encoding="utf-8")
res = fp.read()
fp.close()
print(res)
print("<=111==>")
class MyFile():
# 判断是否创建MyFile该对象
def __new__(cls, filename):
if os.path.exists(filename):
return object.__new__(cls)
return print("该文件不存在")
# 产生文件对象
def __init__(self, filename):
self.fp = open(filename, mode="r", encoding="utf-8")
# 读取文件
def readfile(self):
res = self.fp.read()
return res
def __del__(self):
print(0)
# 自动触发__del__ ,帮助我们关闭文件
self.fp.close()
obj = MyFile("ceshi222.txt")
res = obj.readfile()
print(res)
__call__
魔术方法
- 触发时机:把对象当作函数调用的时候自动触发
- 功能: 模拟函数化操作
- 参数: 参数不固定,至少一个self参数
- 返回值: 看需求
1.基本语法
class MyClass():
def __call__(self):
print("__call__方法被调用")
return "done"
obj = MyClass()
res = obj()
print(res)
- 模拟洗衣服的过程
class Wash():
# 使用call方法,进行统一的调用
def __call__(self, something):
self.something = something
print("以下是洗{}的过程:".format(something))
self.step1()
self.step2()
self.step3()
def step1(self):
print("第一步放水,把{}扔盆里".format(self.something))
def step2(self):
print("第二部导入洗衣液,金纺,蓝月亮,吊牌洗衣皂扔盆里搓")
def step3(self):
print("第三部晒一下,穿上")
obj = Wash()
# 一边写一边骂街
# obj.step1()
# obj.step2()
# obj.step3()
# 小王是个快乐的孩子
obj("裤衩")
- 模拟内置int方法实现myint
# print(int(-5.9))
import math
class MyInt():
def stoi(self, n, sign=1):
res = n.lstrip("0")
if res == "":
return 0
num = eval(res) * sign
return num
def __call__(self, n):
# 判断的是布尔类型
if isinstance(n, bool):
if n:
return 1
else:
return 0
# 判断的是整型
elif isinstance(n, int):
return n
# 判断的是浮点型
elif isinstance(n, float):
if n < 0:
return math.ceil(n)
else:
return math.floor(n)
# 判断的是字符串
elif isinstance(n, str):
if (n[0] == "-" or n[0] == "+") and n[1:].isdecimal():
if n[0] == "+":
sign = 1
elif n[0] == "-":
sign = -1
return self.stoi(n[1:], sign)
elif n.isdecimal():
# 如果能够走到这个条件,一定没有带任何正负号
return self.stoi(n)
else:
return "对不起,老弟,这个算不了"
else:
print("对不起,老哥,这个算不了")
myint = MyInt()
res = myint(False)
print(res)
res = myint(5)
print(res)
res = myint(-5.5)
print(res)
# res = eval("123454")
# print(res,type(res))
res = myint("12345")
print(res,type(res))
# res = int("-00000000000111222abcdfrf")
# print(res)
res = myint("+00000000000111222")
res = myint("*&^%$#@00000000000000000")
print(res)
# res = int("*&^%$#@00000000000000000")
# res = eval("")
# print(res)
res = int(5 + 6)
print(res)
res = myint(5 * 6)
print(res)
res = myint([1,3,4])
res = int([1, 3, 4])
print(res)
__str__
魔术方法
- 触发时机: 使用print(对象)或者str(对象)的时候触发
- 功能: 查看对象
- 参数: 一个self接受当前对象
- 返回值: 必须返回字符串类型
class Cat():
gift = "抓老鼠"
def __init__(self, name):
self.name = name
def cat_info(self):
strvar = "这个对象的名字{},这个对象的天赋:{}".format(self.name, self.gift)
return strvar
def __str__(self):
return self.cat_info()
tom = Cat("汤姆")
# (1) 打印对象触发__str__方法
# print(tom)
# (2) str强转对象时候触发__str__方法
res = str(tom)
print(res)
__repr__
魔术方法
- 触发时机: 使用repr(对象)的时候触发
- 功能: 查看对象,与魔术方法__str__相似
- 参数: 一个self接受当前对象
- 返回值: 必须返回字符串类型
class Mouse():
gift = "打洞"
def __init__(self, name):
self.name = name
def mouse_info(self):
strvar = "该对象的名字{},它的天赋是{},龙胜龙,凤生凤,老鼠的儿子会打洞".format(
self.name, self.gift)
return strvar
def __repr__(self):
return self.mouse_info()
# 在系统的底层加了如下一句话:如果存在__repr__ 这个方法,就把它赋值给__str__
# __str__ = __repr__
jerry = Mouse("杰瑞")
res = repr(jerry)
print(res)
print(jerry)
__bool__
魔术方法
- 触发时机:使用bool(对象)的时候自动触发
- 功能:强转对象
- 参数:一个self接受当前对象
- 返回值:必须是布尔类型
类似的还有如下等等(了解):
__complex__(self) 被complex强转对象时调用
__int__(self) 被int强转对象时调用
__float__(self) 被float强转对象时调用
…
…
class MyBool():
def __bool__(self):
print(122)
# return True
return False
obj = MyBool()
res = bool(obj)
print(res)
__add__
魔术方法
(与之相关的__radd__ 反向加法)
- 触发时机:使用对象进行运算相加的时候自动触发
- 功能:对象运算
- 参数:二个对象参数
- 返回值:运算后的值
类似的还有如下等等(了解):
__sub__(self, other) 定义减法的行为:-
__mul__(self, other) 定义乘法的行为:*
__truediv__(self, other) 定义真除法的行为:/
…
…
class MyAdd():
def __init__(self, num):
self.num = num
# 对象+数值,并且对象在+加号的左边,自动触发__add__方法
def __add__(self, other):
# self.num => 3 + 56 => 59
return self.num + other
def __radd__(self, other):
# self 接受b, other 接受33
return self.num + other * 10
# 1.当对象在加号的左侧 自动触发add 方法
a = MyAdd(3)
res = a + 56
print(res)
# 2.当对象在加号的右侧 自动触发radd 方法
b = MyAdd(5)
res = 33 + b
print(res)
# 3 a+b =?
res = a + b
print(res)
'''
a在加号的左侧,触发add魔术方法
self.num + other => 3 + b
b在加号的右侧,触发radd魔术方法
res = 3+b
self.num + other * 10 => 5 + 3 *10 => 35
'''
__len__
魔术方法
- 触发时机:使用len(对象)的时候自动触发
- 功能:用于检测对象中或者类中某个内容的个数
- 参数:一个self接受当前对象
- 返回值:必须返回整型
类似的还有如下等等(了解):
__iter__(self) 定义迭代容器中的元素的行为
__reversed__(self) 定义当被 reversed() 调用时的行为
__contains__(self, item) 定义当使用成员测试运算符(in 或 not in)时的行为
…
…
用len(对象)方式,算出该对象所归属的类有多少自定义成员
class MyLen():
pty1 = 1
pty2 = 2
__pty3 = 3
def func1():
pass
def func2():
pass
def __func3():
pass
def __func4():
pass
def __func5():
pass
def __len__(self):
# print(MyLen.__dict__)
dic = MyLen.__dict__
lst = [i for i in dic if not(i.startswith("__") and i.endswith("__"))]
num = len(lst)
return num
obj = MyLen()
res = len(obj)
print(res)
"""
{'__module__': '__main__',
'pty1': 1, 'pty2': 2,
'_MyLen__pty3': 3,
'func1': <function MyLen.func1 at 0x7f10880d9620>, 'func2': <function MyLen.func2 at 0x7f10880d96a8>,
'_MyLen__func3': <function MyLen.__func3 at 0x7f10880d9730>, '__len__': <function MyLen.__len__ at 0x7f10880d97b8>,
'__dict__': <attribute '__dict__' of 'MyLen' objects>,
'__weakref__': <attribute '__weakref__' of 'MyLen' objects>, '__doc__': None}
"""