day25:魔术方法
目录
一个小表格方便记忆哈

__del__ (析构方法)
__del__简要介绍
1.触发时机:当对象被内存回收的时候自动触发
(1)页面执行完毕回收所有变量
(2)所有对象被del的时候
2.功能:对象使用完毕后资源回收
3.参数:一个self接受对象
4.返回值:无
第一种情况:页面执行完毕回收所有变量
class LangDog():
food = "改吃蔬菜" def __init__(self, name):
self.name = name def __del__(self):
print("析构方法被触发")
print("0001=====")
obj = LangDog("肉丝")
print("0002=====")
# 1.页面执行完毕回收所有变量
print(obj.name) # 当执行完这句话后,才算页面执行完毕,这个时候触发__del__析构方法 '''
运行结果:
=====
=====
肉丝
析构方法被触发
'''
第二种情况:所有对象被del的时候
如何理解第二种情况中所说到的所有对象?

代码如下:
class LangDog():
food = "改吃蔬菜" def __init__(self, name):
self.name = name def __del__(self):
print("析构方法被触发") obj1 = LangDog("肉丝")
obj2 = obj1
print("<=====start=====>")
del obj1
print("<=====end=====>")
打印结果:

虽然obj1对象被删除了,但是obj2对象并没有被删除,所以不会触发析构方法
打印了“析构方法被触发”是因为整个页面执行完毕了,也会触发析构方法
使用__del__模拟文件操作
# 3.模拟文件操作
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):
# 读取文件
return self.fp.read() def __del__(self):
# 关闭文件
self.fp.close() obj = ReadFile("1.txt") if obj is not None:
res = obj.readcontent()
print(res)
else:
print("没有该类文件") # 当然,也可以用三元运算符来实现
""" 真值 if 条件表达式 else 假值 """
print(obj.readcontent()) if obj is not None else print("没有该类文件")
魔术方法:__str__
__str__简要介绍
1.触发时机: 使用print(对象)或者str(对象)的时候触发
2.功能: 查看对象
3.参数: 一个self接受当前对象
4.返回值: 必须返回字符串类型
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,5000) # __repr__ = __str__ tom = Cat("汤姆")
# 方法一. print(对象)
print(tom)
# 方法二. str(对象)
res = str(tom)
print(res)
魔术方法:__repr__
1.触发时机: 使用repr(对象)的时候触发
2.功能: 查看对象,与魔术方法__str__相似
3.参数: 一个self接受当前对象
4.返回值: 必须返回字符串类型
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) # 系统在底层,自动加了一句赋值操作
__str__ = __repr__ jerry = Mouse("杰瑞")
res = repr(jerry)
print(res) # 因为系统底层赋值的原因,在打印对象或者强转对象为字符串的时候,仍然可以触发;
print(jerry)
res = str(jerry)
print(res)
魔术方法:__call__
1.触发时机:把对象当作函数调用的时候自动触发
2.功能: 模拟函数化操作
3.参数: 参数不固定,至少一个self参数
4.返回值: 看需求
基本用法
# (1) 基本用法
class MyClass():
a = 1
def __call__(self):
print("call魔术方法被触发了") obj = MyClass() # 实例化一个对象
obj() # 把对象当做函数调用,此时会触发__call__方法
模拟洗衣服的过程
# (2) 模拟洗衣服的过程
class Wash(): def __call__(self,something):
print("我现在要洗{}".format(something))
self.step1()
self.step2()
self.step3()
return "洗完了" def step1(self):
print("加热水,家洗衣粉,加洗衣液,加洗涤剂") def step2(self):
print("衣服泡进去搅乱 打散 搓一搓~ ") def step3(self):
print("脱水,穿上") obj = Wash() # 方法一
# obj.step1()
# obj.step2()
# obj.step3() # 方法二
res = obj("衣服") # 把对象obj当做函数进行调用,此时触发__call__方法,执行__call__方法所有内容
print(res)
模拟内置的int方法,实现相应的操作(有时间再分析)
# (3) 模拟内置int 实现相应的操作
import math
class MyInt(): def calc(self,num,sign=1):
# print(num,sign) # 去掉左边多余的0
strvar = num.lstrip("")
# print(strvar) # 为了防止都是0 ,如果去掉之后为空,返回0
if strvar == "":
return 0 # 正常情况下,执行存数字字符串变成数字 , 在乘上相应的符号,得出最后的结果
return eval(strvar) * sign def __call__(self,num):
if isinstance(num , bool):
if num == True:
return 1
elif num == False:
return 0 elif isinstance(num,int):
return num elif isinstance(num,float):
# 方法一
"""
strvar = str(num)
lst = strvar.split(".")
return eval(lst[0])
"""
# 方法二
"""
if num >= 0:
return math.floor(num)
else:
return math.ceil(num)
"""
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.calc(num[1:],sign) elif num.isdecimal():
return self.calc(num)
else:
return "老铁,这个真转不了" myint = MyInt()
# myint(5) => 5
# myint(3.14) => 3 res = myint(True)
print(res)
res = myint(100)
print(res)
res = myint(3333.14)
print(res, type(res)) #
# bool int float "12312312323" # int(3.14) => 3
print(int(3.14)) #
print(int(-3.14)) # -3
print("<===>")
print(myint(3.14))
print(myint(-0.2)) print("<===>")
print(int(""))
print(int(""),"")
print(int("+000000000000000000000000000000000000000000123"))
print(int("-000000000000000000000000000000000000000000123"))
print(int("")) print("<==111=>")
print(myint("+000000000234"))
print(myint(""))
print(myint(""))
print(myint("3.143434"))
print(myint(+-++-+-+-+-+-+-+-+-+-+-++++++++-----234234),"<====>")
print(int(+-++-+-+-+-+-+-+-+-+-+-++++++++-----234234),"<====>") """
exec("a = 3")
print(a) eval("4")
"""
# print(math.floor(0.14)) # 0
# print(math.floor(3.14)) # 3
# print(math.ceil(-3.14)) # -3
魔术方法:__bool__
__bool__简要介绍
1.触发时机:使用bool(对象)的时候自动触发
2.功能:强转对象
3.参数:一个self接受当前对象
4.返回值:必须是布尔类型
class MyClass():
def __bool__(self):
return False obj = MyClass()
res = bool(obj)
print(res)
类似的还有如下等等(了解):
__complex__(self) 被complex强转对象时调用
__int__(self) 被int强转对象时调用
__float__(self) 被float强转对象时调用
...
...
魔术方法:__add__,__radd__
__add__简要介绍
1.触发时机:使用对象进行运算相加的时候自动触发
2.功能:对象运算
3.参数:二个对象参数
4.返回值:运算后的值
5.注意点:
对象在加号+的左侧时,自动触发__add__方法
对象在加号+的右侧时,自动触发__radd__方法
加号左侧和右侧都是对象时,先触发__add__方法,再触发__radd__方法
class MyClass1():
def __init__(self,num):
self.num = num # 对象在加号+的左侧时,自动触发
def __add__(self,other):
# print(self)
# print(other)
return self.num + other # return 10 + 7 = 17 # 对象在加号+的右侧时,自动触发
def __radd__(self,other):
# print(self)
# print(other)
return self.num * 2 + other # 第一种
a = MyClass1(10)
res = a + 7
print(res) # 第二种
b = MyClass1(5)
res = 20 + b
print(res) # 第三种
print("<============>")
res = a+b
print(res)
"""
第一次触发魔术方法, a+ =>触发__add__方法
self => a other => b
self.num + other => a.num+ b => 10 + b res = 10 + b
第二次触发魔术方法 __radd__
self => b other=> 10
self.num * 2 + other => b.num*2 + other => 5 * 2 + 10 => 20
res = 20
"""
类似的还有如下等等(了解):
__sub__(self, other) 定义减法的行为:-
__mul__(self, other) 定义乘法的行为:*
__truediv__(self, other) 定义真除法的行为:/
...
...
魔术方法:__len__
__len__简要介绍
1.触发时机:使用len(对象)的时候自动触发
2.功能:用于检测对象中或者类中成员的个数
3.参数:一个self接受当前对象
4.返回值:必须返回整型
class MyClass():
pty1 = 1
pty2 = 2
__pty3 = 3
pyt3 =10
pty100 = 90 def func1():
pass def __func2():
pass def __func3():
pass def __len__(self):
lst = []
dic = MyClass.__dict__
# 方法一 # print(MyClass.__dict__) # 获取类当中的所有成员
# print(object.__dict__) # 获取对象中的所有成员
dic = MyClass.__dict__ # 遍历类中所有成员
for i in dic: # 遍历类中所有成员
if not(i.startswith("__") and i.endswith("__")): # 如果开头和结尾都不是以双下划线结尾
lst.append(i) # 将符合条件的成员添加到列表中 return len(lst) # 方法二
lst = [i for i in dic if not(i.startswith("__") and i.endswith("__"))]
return len(lst)
与类相关的魔术属性
__dict__ 获取对象或类的内部成员结构
__doc__ 获取对象或类的内部文档
__name__ 获取类名函数名
__class__ 获取当前对象所属的类
__bases__ 获取一个类直接继承的所有父类,返回元组
class Man():
pass class Woman():
pass class Children(Man,Woman): """
功能: 描述小孩天生的属性
成员属性:eye , skin
成员方法:skylight , moonread , __makebaby
""" eye = "万花筒血轮眼"
skin = "白色" def skylight(self):
print("宇智波家族的小孩,天生能够发动天照技能") def moonread(self,func):
# func = func111
print("宇智波家族的小孩,能够发动月亮的光照消灭你~")
res = func.__name__
print(res,type(res)) def __makebaby(self):
print("这一手招数,只能我自己用") # __dict__ 获取对象或类的内部成员结构
obj = Children()
print(obj.__dict__)
print(Children.__dict__) # __doc__ 获取对象或类的内部文档
print(obj.__doc__)
print(Children.__doc__) # __name__ 获取类名函数名
def func111():
print("我是func111方法")
# 获取函数名
obj.moonread(func111)
# 获取类名
obj.moonread(Man) # __class__ 获取当前对象所属的类
print(obj.__class__) # __bases__ 获取一个类直接继承的所有父类,返回元组
print(Children.__bases__)
day25:魔术方法的更多相关文章
- PHP基础知识之魔术方法
__construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sle ...
- 前端学PHP之面向对象系列第二篇——魔术方法
× 目录 [1]构造方法 [2]析构方法 [3]不可访问属性[4]对象复制[5]字符串[6]对象不存在[7]自动加载类[8]串行化[9]函数调用 前面的话 php在面向对象部分有很多相关的魔术方法,这 ...
- PHP中的魔术方法(2)
1.__get.__set这两个方法是为在类和他们的父类中没有声明的属性而设计的__get( $property ) 当调用一个未定义的属性时访问此方法__set( $property, $value ...
- 魔术方法__sleep 和 __wakeup
感觉序列化和反序列化用得倒是比较少了,而json_encode和json_decode用得相对多,都是转化成串,进行入库.传输等.json更方便,但是序列化和反序列化结合这两个魔术方法使用倒还行< ...
- Python魔术方法-Magic Method
介绍 在Python中,所有以"__"双下划线包起来的方法,都统称为"Magic Method",例如类的初始化方法 __init__ ,Python中所有的魔 ...
- php魔术方法使用场景
php魔术方法-----__tostring(),__invoke,__call(),__callStatic ... __tostring(),__invoke() __tostring()方法是在 ...
- PHP中的魔术方法:__construct, __destruct , __call, __callStatic,__get, __set, __isset, __unset , __sleep, __wakeup, __toString, __set_state, __clone and __autoload
1.__get.__set 这两个方法是为在类和他们的父类中没有声明的属性而设计的: __get( $property ) 当调用一个未定义的属性时访问此方法: __set( $property, $ ...
- PHP 类中的魔术方法
定义: PHP类中以两个下画线“__”开头的方法被称为魔术方法. 分类: 例如:构造方法:__construct:析构方法:__destruct:动态重载:__set().__get().__call ...
- php中的魔术方法
__construct 构造器是一个魔术方法,当对象被实例化时它会被调用.在一个类声明时它常常是第一件做的事但是没得必要他也像其他任何方法在类中任何地方都可以声明,构造器也能像其他方法样继承.如果我们 ...
随机推荐
- python 生成器(五):生成器实例(一)创建数据处理管道
问题 你想以数据管道(类似Unix管道)的方式迭代处理数据. 比如,你有个大量的数据需要处理,但是不能将它们一次性放入内存中. 解决方案 生成器函数是一个实现管道机制的好办法. 为了演示,假定你要处理 ...
- 记录groupby的一次操作
df = pd.DataFrame({'key1':list('aabba'), 'key2': ['one','two','one','two','one'], 'data1': np.random ...
- iis 0x80070032 Cannot read configuration file because it exceeds the maximum file size
问题:iis部署了网站,由于webconfig文件过大(251kb,默认250kb)导致网站报错 0x80070032 Cannot read configuration file because i ...
- Web Scraping using Python Scrapy_BS4 - Introduction
What is Web Scraping This is also referred to as web harvesting and web data extraction. This is the ...
- try-catch- finally块中, finally块唯一不执行的情况是什么?
除非在try块或者catch块中调用了退出虚拟机的方法(即System.exit(1);),否则不管在try块.catch块中执行怎样的代码,出现怎样的情况,异常处理的finally块总是会被执行的 ...
- 干货分享:Python Web 部署方式大全
不要让服务器裸奔 学过PHP的都了解,php的正式环境部署非常简单,改几个文件就OK,用FastCgi方式也是分分钟的事情.相比起来,Python在web应用上的部署就繁杂的多,主要是工具繁多,主流服 ...
- MySQL数据库---库的操作
MySQL数据库中,以库,表,记录的形式管理所有的数据,安装MySQL数据库的服务器上可以包含多个库,一个库中包含多张表,一张表中包含多条记录.库对应的是文件系统中文件夹的概念,表对应的是文件的概念, ...
- Html笔试复习
掌握学习技巧,提高学习质量 学习目标:熟练掌握Html笔试复习题 已掌握目标:Html笔试复习题掌握95% 未完成目标:个别题因粗心造成错误,因选项意思不懂出错 解决方案:了解原因,因错出方案,充分利 ...
- 遍历map的6种方式
1,平时开发中对map的使用很多,然后发现了很多map可能存在的各种问题:如HashMap 需要放置 1024 个元素,由于没有设置容量初始大小,随着元素不断增加,容量 7 次被迫扩大,resize ...
- jenkins集群(三) -- master和slave配置git
一.Linux(master)上安装git 1.运行命令:yum -y install git 2.git的默认安装目录是: 二.给Linux下Git配置好秘钥(公钥 + 私钥) 1.添加用户和密码 ...