033.Python的__del__析构方法he__call__方法
一 __del__ 魔术方法(析构方法)
1.1 介绍
- 触发时机:当对象被内存回收的时候自动触发[1.页面执行完毕回收所有变量 2.所有对象被del的时候]
- 功能:对象使用完毕后资源回收
- 参数:一个self接受对象
- 返回值:无
1.2 页面执行完毕回收所有变量
class Plane():
def __init__(self,name):
self.name = name
def fly(self):
print ("我的飞机是{}飞的很快".format(self.name))
def __del__(self):
print ("析构被触发")
obj = Plane("高超音速")
obj.fly()
执行
[root@node10 python]# python3 test.py
我的飞机是高超音速飞的很快
析构被触发
1.3 所有对象被del的时候
删除对象
class Plane():
def __init__(self,name):
self.name = name
def fly(self):
print ("我的飞机是{}飞的很快".format(self.name))
def __del__(self):
print ("析构被触发")
obj = Plane("高超音速")
print ("<=======================start del=========================>")
del obj
print ("<=======================end del=========================>")
执行
[root@node10 python]# python3 test.py
<=======================start del=========================>
析构被触发
<=======================end del=========================>
当只删除一个对象,还有剩余对象,也不会触发
class Plane():
def __init__(self,name):
self.name = name
def fly(self):
print ("我的飞机是{}飞的很快".format(self.name))
def __del__(self):
print ("析构被触发")
obj = Plane("高超音速")
obj2 = obj
print ("<=======================start del=========================>")
del obj
print ("<=======================end del=========================>")
执行,是在页面执行完毕是触发
[root@node10 python]# python3 test.py
<=======================start del=========================>
<=======================end del=========================>
析构被触发
1.4 删除所有对象
- 两个不同的变量指向同一个对象,只有把这两个变量都删除了,
- 这个对象没有变量引用了,才会真正的删除对象.
class Plane():
def __init__(self,name):
self.name = name
def fly(self):
print ("我的飞机是{}飞的很快".format(self.name))
def __del__(self):
print ("析构被触发")
obj = Plane("高超音速")
obj2 = obj
print ("<=======================start del=========================>")
del obj
del obj2
print ("<=======================end del=========================>")
执行
[root@node10 python]# python3 test.py
<=======================start del=========================>
析构被触发
<=======================end del=========================>
1.5 模拟文件读的操作
fp = open("ceshi.txt","r",encoding="utf-8")
res = fp.read()
print (res)
执行
[root@node10 python]# cat ceshi.txt
君临天下
[root@node10 python]# python3 test.py
君临天下
有这个文件,就创建一个对象
fp = open("ceshi.txt","r",encoding="utf-8")
res = fp.read()
fp.close()
print (res)
import os
class ReadFile():
def __new__(cls,name):
if os.path.exists(name):
return object.__new__(cls)
return print("没有这个文件")
obj=ReadFile("ceshi.txt")
print (obj)
执行
[root@node10 python]# python3 test.py
君临天下 <__main__.ReadFile object at 0x7f5c2271b518>
如果不存在
fp = open("ceshi.txt","r",encoding="utf-8")
res = fp.read()
fp.close()
print (res)
import os
class ReadFile():
def __new__(cls,name):
if os.path.exists(name):
return object.__new__(cls)
return print("没有这个文件")
obj=ReadFile("ceshii11.txt")
print (obj)
执行
[root@node10 python]# python3 test.py
君临天下 没有这个文件
None
1.6 对对象进行初始化
import os
class ReadFile():
def __new__(cls,name):
if os.path.exists(name):
return object.__new__(cls)
return print("没有这个文件")
def __init__(self,name):
self.fp = open("ceshi.txt","r",encoding="utf-8")
def readcontent(self):
res = self.fp.read()
return (res)
def __del__(self):
self.fp.close()
obj=ReadFile("ceshi.txt")
print (obj)
res = obj.readcontent()
print (res)
执行
[root@node10 python]# python3 test.py
<__main__.ReadFile object at 0x7f601b50e470>
君临天下
如果文件不存在
import os
class ReadFile():
#创建对象
def __new__(cls,name):
if os.path.exists(name):
return object.__new__(cls)
return print("没有这个文件")
def __init__(self,name):
#把文件对象赋值给该对象的fp成员属性
self.fp = open("ceshi.txt","r",encoding="utf-8")
#读取文件内容
def readcontent(self):
res = self.fp.read()
return (res)
#关闭文件
def __del__(self):
self.fp.close()
obj=ReadFile("ceshi111.txt")
print (obj)
res = obj.readcontent()
print (res)
执行

二 __call__ 魔术方法
2.1 介绍
- 触发时机:把对象当作函数调用的时候自动触发
- 功能: 模拟函数化操作
- 参数: 参数不固定,至少一个self参数
- 返回值: 看需求
2.2 基本用法
把对象当成函数进行调用,自动触发__call__
class MyClass():
def __call__(self):
print ("call方法被调用")
obj = MyClass()
obj()
执行
[root@node10 python]# python3 test.py
call方法被调用
如果没有__call__调用就会出错
class MyClass():
# def __call__(self):
# print ("call方法被调用")
pass
obj = MyClass()
obj()
执行报错

2.3 模拟购物过程
class Shopping():
def __init__(self,who):
self.who = who
def step1(self):
print ("{}出门".format(self.who))
def step2(self):
print ("{}开车去商场".format(self.who))
def step3(self):
print ("{}买完东西回家".format(self.who))
obj = Shopping("女朋友")
obj.step1()
obj.step2()
obj.step3()
执行
[root@node10 python]# python3 test.py
女朋友出门
女朋友开车去商场
女朋友买完东西回家
2.4 使用__call__方法
class Shopping():
def __init__(self,who):
self.who = who
def __call__(self):
self.step1()
self.step2()
self.step3()
def step1(self):
print ("{}出门".format(self.who))
def step2(self):
print ("{}开车去商场".format(self.who))
def step3(self):
print ("{}买完东西回家".format(self.who))
obj = Shopping("女朋友")
obj()
执行
[root@node10 python]# python3 test.py
女朋友出门
女朋友开车去商场
女朋友买完东西回家
2.5 优化1
class Shopping():
def __init__(self,who):
self.who = who
def __call__(self,shop):
self.shop = shop
print ("我的{}要去{}".format(self.who,self.shop))
self.step1()
self.step2()
self.step3()
def step1(self):
print ("{}出门".format(self.who))
def step2(self):
print ("{}开车去商场".format(self.who))
def step3(self):
print ("{}买完东西回家".format(self.who))
obj = Shopping("女朋友")
obj("购物")
执行
[root@node10 python]# python3 test.py
我的女朋友要去购物
女朋友出门
女朋友开车去商场
女朋友买完东西回家
2.6 不使用初始化
class Shopping():
def __call__(self,who):
self.who = who
print ("我的{}要去购物".format(self.who))
self.step1()
self.step2()
self.step3()
def step1(self):
print ("{}出门".format(self.who))
def step2(self):
print ("{}开车去商场".format(self.who))
def step3(self):
print ("{}买完东西回家".format(self.who))
obj = Shopping()
obj("女朋友")
执行
[root@node10 python]# python3 test.py
我的女朋友要去购物
女朋友出门
女朋友开车去商场
女朋友买完东西回家
2.7 优化2
class Shopping():
def __call__(self,who,shop):
self.who = who
self.shop = shop
print ("我的{}要去{}".format(self.who,self.shop))
self.step1()
self.step2()
self.step3()
def step1(self):
print ("{}出门".format(self.who))
def step2(self):
print ("{}开车去商场".format(self.who))
def step3(self):
print ("{}买完东西回家".format(self.who))
obj = Shopping()
obj("女朋友","购物")
执行
[root@node10 python]# python3 test.py
我的女朋友要去购物
女朋友出门
女朋友开车去商场
女朋友买完东西回家
2.8 模拟内置int强转方法 myint
import math
class MyInt():
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):
if num < 0:
return math.ceil(num)
else:
return math.floor(num)
myint = MyInt()
print (myint(True))
print (myint(False)) print ("<int type>")
print (myint(55)) print ("<float type>")
print (myint(6.9))
print (myint(-6.9))
执行
[root@node10 python]# python3 test.py
1
0
<int type>
55
<float type>
6
-6
判断字符串类型
import math
class MyInt():
# sign 代表符号,默认正值
def myfunc(self,strvar,sign = 1):
isnull = strvar.lstrip("0")
# 判断是否处理完的字符串是不是空的,如果是空的,这个串是"0000.."是因为eval("")会出现错误
if isnull == "":
return 0
res = eval(strvar) * sign
return res
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):
if num < 0:
return math.ceil(num)
else:
return math.floor(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.myfunc(num[1:],sign)
elif num.isdecimal():
return self.myfunc(num)
else: return "对不起,处理不了这个数据类型"
myint = MyInt()
print (myint(True))
print (myint(False)) print ("<int type>")
print (myint(55)) print ("<float type>")
print (myint(6.9))
print (myint(-6.9))
print ("<str type>")
print(myint("11122233"),type(myint("11122233")))
# print(myint("00001223"))
print(myint("-11122233"),type(myint("-11122233")))
print(myint([1,2,3,4]))
执行
[root@node10 python]# python3 test.py
1
0
<int type>
55
<float type>
6
-6
<str type>
11122233 <class 'int'>
-11122233 <class 'int'>
对不起,处理不了这个数据类型
使用eval可以转化为数字,但是在特殊情况下并不能执行
但是空值,带-号的会
[root@node10 python]# cat test.py
import math
class MyInt():
# sign 代表符号,默认正值
def myfunc(self,strvar,sign = 1):
isnull = strvar.lstrip("0")
# 判断是否处理完的字符串是不是空的,如果是空的,这个串是"0000.."
if isnull == "":
return 0
res = eval(strvar) * sign
return res
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):
if num < 0:
return math.ceil(num)
else:
return math.floor(num)
elif isinstance(num,str):
if num.isdecimal():
#或者使用self.myfunc(num)
res = eval(num)
return res
else: return "对不起,处理不了这个数据类型"
myint = MyInt()
print (myint(True))
print (myint(False)) print ("<int type>")
print (myint(55)) print ("<float type>")
print (myint(6.9))
print (myint(-6.9))
print ("<str type>")
print (myint("1234"))
print (myint("-234"))
print (myint("00000234"))
执行

2.9 使用__call__方法实现装饰器
普通方式
class Show():
def showtime(func):
def newfunc():
print ("准备演出")
func()
print ("退出演出")
return newfunc
@Show.showtime
def func():
print ("张靓颖正在鸟巢演出")
func()
执行
[root@node10 python]# python3 test.py
准备演出
张靓颖正在鸟巢演出
退出演出
使用__call__
[root@node10 python]# cat test.py
class Show():
def __call__(self,func):
return self.showtime(func)
def showtime(self,func):
def newfunc():
print ("准备演出")
func()
print ("退出演出")
return newfunc
@Show() #@obj =>func = obj(func) => 返回的新函数替换旧函数
def func():
print ("张靓颖正在鸟巢演出")
func()
执行
[root@node10 python]# python3 test.py
准备演出
张靓颖正在鸟巢演出
退出演出
@有两个作用
(1)自动把装饰器下面的函数当成参数进行传递
(2)把返回的新函数,自动赋值,用来替换旧函数
执行过程
Show()返回一个obj对象
@obj发动技能,把参数传递给obj
obj(func)返回newfunc
@发动技能,把新函数替换旧函数
func = newfunc,则func()就等价于newfunc()
033.Python的__del__析构方法he__call__方法的更多相关文章
- python - class内置方法 doc/module/del(析构方法)/cal 方法
__doc__ # __doc__ #摘要信息 #这个属性不会继承给子类 class Test(): """这是摘要信息""" pass x ...
- 【python】-- 类的装饰器方法、特殊成员方法
装饰器方法 类的另外的特性,装饰器方法:静态方法(staticmethod).类方法(classmethod).属性方法(property) 一.静态方法 在方法名前加上@staticmethod装饰 ...
- 【python学习笔记】9.魔法方法、属性和迭代器
[python学习笔记]9.魔法方法.属性和迭代器 魔法方法:xx, 收尾各有两个下划线的方法 __init__(self): 构造方法,创建对象时候自动执行,可以为其增加参数, 父类构造方法不会被自 ...
- python面向对象 : 反射和内置方法
一. 反射 1. isinstance()和issubclass() isinstance( 对象名, 类名) : 判断对象所属关系,包括父类 (注:type(对象名) is 类名 : 判断对象所属 ...
- __del__,item系列 ,hash方法,__eq__,
# 构造方法 申请一个空间# 析构方法 释放一个空间 # 某个对象借用了操作系统的资源,还要通过析构方法归还回去:文件资源 网络资源 # 垃圾回收机制 class A: def __del__(sel ...
- [ python ] 类中的一些特殊方法
item系列 __getitem__(self, item) 对象通过 object[key] 触发 __setitem__(self, key, value) 对象通过 object[key] = ...
- Python面向对象之常用的特殊方法(5)
Python面向对象里面有很多特殊方法,例如__init__(构造方法),__del__(析构方法),这些方法对于面向对象编程非常重要,下面列出一些常用的特殊方法 (1)__call__ class ...
- Python构造器及析构器:__init__与__new__及__del__
__init__与__new__这两个魔法方法组成了Python类对象的构造器,在Python类实例化时,其实最先调用的不是__init__而是__new__.__new__是负责实例化对象的,而__ ...
- Python面向对象之反射,双下方法
一. 反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序 ...
随机推荐
- 「Unity卡牌自走棋」项目NABCD分析
项目 内容 这个作业属于哪个课程 2021学年春季软件工程(罗杰 任健) 这个作业的要求在哪里 团队项目-初次邂逅,需求分析 在这个课程的目标是 锻炼在大规模开发中的团队协作能力 这个作业在哪个具体方 ...
- Git版本控制之-创建配置本地git仓库
查看全局配置:code .gitconfig [code 就代表的用vscode 打开gitconfig 文件,如果是 sublime 就是 subl ][如果打开失败说明环境变量没有配置] [只有配 ...
- Python:函数解释(面向过程)
1. 函数概述 在编程的语境下,函数 (function) 是指一个有命名的.执行某个计算的语句序列 (sequence of statements) .函数可以针对某类问题建立了通用解决步骤(算法) ...
- matlab文件管理
当前文价夹浏览器以及路径管理器 在主页面左侧有单独的窗口进行显示,可以显示当前目录下的文件并提供文件搜索功能. 搜索路径 搜索先后步骤 输入字符串"polyfit" (1)检查 ...
- kubernetes之pod拓扑分布约束
在日常使用 kubernetes 的过程中中,很多时候我们并没有过多的关心 pod 的到底调度在哪里,只是通过多副本的测试,来提高的我们的业务的可用性,但是当多个相同业务 pod 在分布在相同节点时, ...
- 2020北航OO第二单元总结
2020北航OO第二单元总结 前言 本单元考察基于多线程的电梯调度问题,成功让我从一个多线程小白到了基本掌握了使用锁来控制线程安全的能力,收获颇多(充分体验了迷茫地de一个又一个死锁bug的痛苦). ...
- 源码篇:ThreadLocal的奇思妙想(万字图文)
前言 ThreadLocal的文章在网上也有不少,但是看了一些后,理解起来总感觉有绕,而且看了ThreadLocal的源码,无论是线程隔离.类环形数组.弱引用结构等等,实在是太有意思了!我必须也要让大 ...
- 浅谈Asp.net Mvc之Action如何传多个参数的方法
最近,工作上有一个需要:用户查询日志文件信息,查看某一个具体日志信息,可能同时查看该日志所在日期的其他日志信息列表. 为完成此功能,我打算在URL中传入了两个参数,一个记录此日志时间,另外一个记录日志 ...
- php实现redis消息发布订阅
基础介绍 Pub/Sub功能(means Publish, Subscribe)即发布及订阅功能 基于事件的系统中,Pub/Sub是目前广泛使用的通信模型,它采用事件作为基本的通信机制,提供大规模系统 ...
- 【JVM】Java8 和 Java7中JVM内存模型有什么区别
规范和实现 针对Java虚拟机的实现有专门的<Java虚拟机规范>,在遵守规范的前提下,不同的厂商会对虚拟机进行不同的实现. 就好比开发的过程中定义了接口,具体的接口实现大家可以根据不同的 ...