delstr函数python_python3全栈开发-内置函数补充,反射,元类,__str__,__del__,exec,type,__call__方法...

本文详细介绍了Python中的反射机制,包括hasattr、getattr、setattr和delattr等函数的使用。接着讲解了元类的概念,如何使用type创建和控制类,并展示了__call__方法的运用。此外,文章还讨论了对象的生命周期,特别是__del__方法在资源管理中的作用。最后,通过一个单例模式的实现,展示了如何确保类只有一个实例。
摘要由CSDN通过智能技术生成

一、内置函数补充

1、isinstance(obj,cls)检查是否obj是否是类 cls 的对象

classFoo(object):passobj=Foo()print(isinstance(obj, Foo)) #结果为True

2、issubclass(sub, super)检查sub类是否是 super 类的派生类

classFoo(object):pass

classBar(Foo):pass

print(issubclass(Bar, Foo)) #结果为True

二、 反射

1 、什么是反射

反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。

2 、python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

四个可以实现自省的函数:

hasattr、getattr、setattr、delattr

下列方法适用于类和对象(一切皆对象,类本身也是一个对象)

#1、hasattr#print(hasattr(People,'country')) #True#print('country' in People.__dict__) #不知道hasattr方法时,用的方法#print(hasattr(obj,'name')) #True#print(hasattr(obj,'country')) #True#print(hasattr(obj,'tell')) #True

#2、getattr#x=getattr(People,'country1',None) #查找指定属性,没有此属性(提前预防报错写None)显示None,有就返回值#print(x)

#f=getattr(obj,'tell',None)#obj.tell#print(f == obj.tell) #True#f() #正常的调用函数#obj.tell()

#3、setattr#People.x=111#setattr(People,'x',111) #添加x属性,值为111#print(People.x)

#obj.age=18#setattr(obj,"age",18) # 添加age属性,值为18#print(obj.__dict__)

#4、delattr#del People.country #原始的方法#delattr(People,"country")#print(People.__dict__)

#del obj.name#delattr(obj,"name")#print(obj.__dict__)

三、__str__

classPeople:def __init__(self,name,age,sex):

self.name=name

self.age=age

self.sex=sexdef __str__(self):#print('========>')

return '' %(self.name,self.age,self.sex)

obj=People('duoduo',18,'male')print(obj) #print(obj.__str__()) 在print时触发__str__

四、 __del__

当对象在内存中被释放时,自动触发执行。

注:如果产生的对象仅仅只是python程序级别的(用户级),那么无需定义__del__,如果产生的对象的同时还会向操作系统发起系统调用,即一个对象有用户级与内核级两种资源

importtimeclassPeople:def __init__(self,name,age,sex):

self.name=name

self.age=age

self.sex=sexdef __del__(self): #在对象被删除的条件下,自动执行

print('__del__')

obj=People('duoduo',18,'male')#del obj #obj.__del__() #先删除的情况下,直接执行__del__

time.sleep(5) #可以更形象的看出在资源回收前执行__del__

典型的应用场景:

创建数据库类,用该类实例化出数据库链接对象,对象本身是存放于用户空间内存中,而链接则是由操作系统管理的,存放于内核空间内存中

当程序结束时,python只会回收自己的内存空间,即用户态内存,而操作系统的资源则没有被回收,这就需要我们定制__del__,在对象被删除前向操作系统发起关闭数据库链接的系统调用,回收资源

这与文件处理是一个道理:

f=open('a.txt') #做了两件事,在用户空间拿到一个f变量,在操作系统内核空间打开一个文件

del f #只回收用户空间的f,操作系统的文件还处于打开状态#所以我们应该在del f之前保证f.close()执行,即便是没有del,程序执行完毕也会自动del清理资源,于是文件操作的正确用法应该是

f=open('a.txt')

读写...

f.close()

#很多情况下大家都容易忽略f.close,这就用到了with上下文管理classMyOpen: #自己写个打开读文件类,封装内置的opendef __init__(self,filepath,mode="r",encoding="utf-8"):

self.filepath=filepath

self.mode=mode

self.encoding=encoding

self.fobj=open(filepath,mode=mode,encoding=encoding) #申请系统内存def __str__(self):

msg="""filepath:%s

mode:%s

encoding:%s""" %(self.filepath,self.mode,self.encoding)returnmsgdef __del__(self):

self.fobj.close()f=MyOpen('aaa.py',mode='r',encoding='utf-8')#print(f.filepath,f.mode,f.encoding)#print(f)

#print(f.fobj)

res=f.fobj.read() #一样可以读

print(res)

五、exec

#例子 一

code="""#global x #shsh声明x为全局变量

x=0

y=2"""global_dic={'x':100000}

local_dic={} #字符串中声明全局就是全局,不声明就是局部

exec(code,global_dic,local_dic)#

#print(global_dic)#print(local_dic)

#例子 二#code="""#x=1#y=2#def f1(self,a,b):#pass#"""#local_dic={}#exec(code,{},local_dic)#print(local_dic)

六、元类

1、什么是元类:

类的类就是元类

#我们用class定义的类使用来产生我们自己的对象的

#内置元类type是用来专门产生class定义的类的

#一切皆为对象:#Chinese=type(...)

classChinese:

country="China"

def __init__(self,name,age,sex):

self.name=name

self.age=age

self.sex=sexdefspeak(self):print('%s speak Chinese' %self.name)#print(Chinese)#p=Chinese('duoduo',18,'male')#print(type(p)) #最上层的类 type

#print(type(Chinese))

2、用内置的元类type,来实例化得到我们的类

#2、用内置的元类type,来实例化得到我们的类

class_name='Chinese'class_bases=(object,)

lass_body="""country="China"

def __init__(self,name,age,sex):

self.name=name

self.age=age

self.sex=sex

def speak(self):

print('%s speak Chinese' %self.name)"""class_dic={}exec(class_body,{},class_dic)#类的三大要素#print(class_name,class_bases,class_dic)

Chinese=type(class_name,class_bases,class_dic)#print(Chinese)

p=Chinese('duoduo',18,'male')#print(p.name,p.age,p.sex)

3、 __call__

对象后面加括号,触发执行。

注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

classFoo:def __init__(self):pass

def __str__(self):return '123123'

def __del__(self):pass

#调用对象,则会自动触发对象下的绑定方法__call__的执行,

#然后将对象本身当作第一个参数传给self,将调用对象时括号内的值

#传给*args与**kwargs

def __call__(self, *args, **kwargs):print('__call__',args,kwargs)

obj=Foo()#print(obj)

obj(1,2,3,a=1,b=2,c=3) #

4、自定义元类

classMymeta(type):#来控制类Foo的创建

def __init__(self,class_name,class_bases,class_dic): #self=Foo

#print(class_name)

#print(class_bases)

#print(class_dic)

if not class_name.istitle(): #加上判断

raise TypeError('类名的首字母必须大写')if not class_dic.get('__doc__'):raise TypeError('类中必须写好文档注释')

super(Mymeta,self).__init__(class_name,class_bases,class_dic)#控制类Foo的调用过程,即控制实例化Foo的过程

def __call__(self, *args, **kwargs): #self=Foo,args=(1111,) kwargs={}

#print(self)

#print(args)

#print(kwargs)

#1 造一个空对象obj

obj=object.__new__(self)#2、调用Foo.__init__,将obj连同调用Foo括号内的参数一同传给__init__

self.__init__(obj,*args,**kwargs)returnobj#Foo=Mymeta('Foo',(object,),class_dic)

class Foo(object,metaclass=Mymeta):"""文档注释"""x=1

def __init__(self,y):

self.Y=ydeff1(self):print('from f1')

obj=Foo(1111) #Foo.__call__()

#print(obj)#print(obj.y)#print(obj.f1)#print(obj.x)

5、单例模式

import settings #调用配置文件的IP,PORT

classMySQL:__instance=Nonedef __init__(self,ip,port):

self.ip=ip

self.port=port

@classmethod #绑定方法defsingleton(cls):if not cls.__instance:

obj=cls(settings.IP, settings.PORT)

cls.__instance=objreturn cls.__instanceobj1=MySQL('1.1.1.2',3306)

obj2=MySQL('1.1.1.3',3307)

obj3=MySQL('1.1.1.4',3308)#obj4=MySQL(settings.IP,settings.PORT)#print(obj4.ip,obj4.port)

obj4=MySQL.singleton()

obj5=MySQL.singleton()

obj6=MySQL.singleton()print(obj4 is obj5 is obj6) #Ture

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值