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()

执行

[[email protected] 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=========================>")

执行

[[email protected] 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=========================>")

执行,是在页面执行完毕是触发

[[email protected] 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=========================>")

执行

[[email protected] python]# python3 test.py
<=======================start del=========================>
析构被触发
<=======================end del=========================>

1.5 模拟文件读的操作

fp = open("ceshi.txt","r",encoding="utf-8")
res = fp.read()
print (res)

执行

[[email protected] python]# cat ceshi.txt
君临天下
[[email protected] 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)

执行

[[email protected] 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)

执行

[[email protected] 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)

执行

[[email protected] 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()

执行

[[email protected] 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()

执行

[[email protected] 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()

执行

[[email protected] 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("购物")

执行

[[email protected] 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("女朋友")

执行

[[email protected] 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("女朋友","购物")

执行

[[email protected] 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))

执行

[[email protected] 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]))

执行

[[email protected] python]# python3 test.py
1
0
<int type>
55
<float type>
6
-6
<str type>
11122233 <class ‘int‘>
-11122233 <class ‘int‘>对不起,处理不了这个数据类型

使用eval可以转化为数字,但是在特殊情况下并不能执行

但是空值,带-号的会

[[email protected] 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()

执行

[[email protected] python]# python3 test.py
准备演出
张靓颖正在鸟巢演出
退出演出

使用__call__

[[email protected] 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()

执行

[[email protected] python]# python3 test.py
准备演出
张靓颖正在鸟巢演出
退出演出

@有两个作用

(1)自动把装饰器下面的函数当成参数进行传递
(2)把返回的新函数,自动赋值,用来替换旧函数

执行过程

Show()返回一个obj对象

@obj发动技能,把参数传递给obj

obj(func)返回newfunc

@发动技能,把新函数替换旧函数

func = newfunc,则func()就等价于newfunc()

原文地址:https://www.cnblogs.com/zyxnhr/p/12345066.html

时间: 2024-08-26 22:03:46

033.Python的__del__析构方法he__call__方法的相关文章

__del__ 析构方法 __init__ 构造方法

# ### __del__ 析构方法 __init__ 构造方法 ''' 触发时机:当对象被内存回收的时候自动触发[1.页面执行完毕回收所有变量 2.所有对象被del的时候] 功能:对象使用完毕后资源回收 参数:一个self接受对象 返回值:无 ''' class LangDog(): def __init__(self,name): self.name = name def eat(self,something): print("可爱的小狼{},喜欢吃{}".format(self.

【python】-- 类的装饰器方法、特殊成员方法

装饰器方法 类的另外的特性,装饰器方法:静态方法(staticmethod).类方法(classmethod).属性方法(property) 一.静态方法 在方法名前加上@staticmethod装饰器,表示此方法为静态方法 class Dog(object): def __init__(self,name): self.name = name @staticmethod #在方法前加上staticmethod 装饰器定义静态方法 def eat(): print("dog is eating&

Python构造器及析构器:__init__与__new__及__del__

__init__与__new__这两个魔法方法组成了Python类对象的构造器,在Python类实例化时,其实最先调用的不是__init__而是__new__.__new__是负责实例化对象的,而__init__是初始化操作.__del__是析构器,当Python对象的所有引用都不存在了(被del了),就会自动触发__del__执行. class CapStr(str): def __new__(cls, string): #此时string = 'i love you' cls是CapStr这

Python面向对象之反射,双下方法

一. 反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩. python面向对象中的反射:通过字符串的形式操作对象相关的属性.python中的一切事物都是对象(都可以使用反射) 四个可以实现自省的函数 下列方法适用于类和对象(一切皆对象,类本身也是一个对象) class Foo:    f = '

[python] 类常用的内置方法

内置方法 说明 __init__(self,...) 初始化对象,在创建新对象时调用 __del__(self) 释放对象,在对象被删除之前调用 __new__(cls,*args,**kwd) 实例的生成操作 __str__(self) 在使用print语句时被调用 __getitem__(self,key) 获取序列的索引key对应的值,等价于seq[key] __len__(self) 在调用内联函数len()时被调用 __cmp__(stc,dst) 比较两个对象src和dst __ge

python输出颜色与样式的方法

一.输出颜色与样式的方法 上次遇到这个问题就想写下来,其实当时我也不怎么会,老师说这个东西不需要理解,只需要死记硬背,写的多了就记住了,所以今天搜集了几篇文章,加上自己的理解,写下了这篇python 输出颜色的样式与方法的文章,一方面想自己记录下自己的理解,另一方面想用自己通俗的理解送给需要的盆友. 在写python 程序代码的时候,我们知道python输出的字符串颜色和一般字符相同,但是许多时候,我们需要强调某些字符,就需要把其变为易于认出的颜色或者显著的样子. 格式:"\033[字背景颜色:

python 进程内存增长问题, 解决方法和工具

python 进程内存增长问题, 解决方法和工具 表现 解决方法 定位问题过程 gdb-python: 搞清楚python程序在做什么 准备gdb 接入gdb 查看线程 查看调用栈 coredump 其他命令 pyrasite: 连接进入python程序 psutil 查看python进程状态 guppy 取得内存使用的各种对象占用情况 无法回收的对象 不可回收对象的例子 ?? objgraph 查找循环引用 表现 运行环境: # uname -a Linux ** 3.10.0-327.el7

python实现whois查询功能的方法源码

恐怕很多朋友跟我一样,使用python语言居然能实现whois服务器查询功能.下面我把代码和说明搬来给大家看看,有谁需要可以参考下.本来想直接从whois服务器查询的,但是发现要写socket 用43端口链接服务器,但是有些服务器的地址不清楚,而且查询命令貌似有改变所以不想折腾了,就想着直接用chinaz的页面实现一下算了.如下代码是在 win7下操作的,安装python3.2测试通过. Python3.2实现whois查询功能的方法源码: # -*- coding:utf-8 -*- impo

Python类属性访问的魔法方法

Python类属性访问的魔法方法: 1. __getattr__(self, name)- 定义当用户试图获取一个不存在的属性时的行为 2. __getattribute__(self, name)- 定义当该类的属性被访问时的行为 注意:当__getattr__与__getattribute__同时重写时,访问属性时,优先调用__getattribute__,只有当被访问的属性不存在时才触发__getattr__ 3. __setattr__(self, name, value)- 定义当一个