日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

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

發布時間:2025/3/13 python 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python 元类的call_python3 全栈开发 - 内置函数补充, 反射, 元类,__str__,__del__,exec,type,__call__方法... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

python3 全棧開發 - 內置函數補充, 反射, 元類,__str__,__del__,exec,type,__call__方法

一, 內置函數補充

1,isinstance(obj,cls)檢查是否 obj 是否是類 cls 的對象classFoo(object):

pass

obj=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=sex

def__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__, 如果產生的對象的同時還會向操作系統發起系統調用, 即一個對象有用戶級與內核級兩種資源importtime

classPeople:

def__init__(self,name,age,sex):

self.name=name

self.age=age

self.sex=sex

def__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 變量, 在操作系統內核空間打開一個文件

delf#只回收用戶空間的 f, 操作系統的文件還處于打開狀態

# 所以我們應該在 del f 之前保證 f.close()執行, 即便是沒有 del, 程序執行完畢也會自動 del 清理資源, 于是文件操作的正確用法應該是

f=open('a.txt')

讀寫...f.close()

# 很多情況下大家都容易忽略 f.close, 這就用到了 with 上下文管理

classMyOpen:#自己寫個打開讀文件類, 封裝內置的 open

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

returnmsg

def__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=sex

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

ifnotclass_name.istitle():#加上判斷

raiseTypeError('類名的首字母必須大寫')

ifnotclass_dic.get('__doc__'):

raiseTypeError('類中必須寫好文檔注釋')

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)

classFoo(object,metaclass=Mymeta):

"""文檔注釋"""

x=1

def__init__(self,y):

self.Y=y

deff1(self):

print('from f1')

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

# print(obj)

# print(obj.y)

# print(obj.f1)

# print(obj.x)

5, 單例模式importsettings#調用配置文件的 IP,PORT

classMySQL:

__instance=None

def__init__(self,ip,port):

self.ip=ip

self.port=port

@classmethod#綁定方法

defsingleton(cls):

ifnotcls.__instance:

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

cls.__instance=obj

returncls.__instance

obj1=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(obj4isobj5isobj6)#Ture

來源: https://www.cnblogs.com/ManyQian/p/8868350.html

總結

以上是生活随笔為你收集整理的python 元类的call_python3 全栈开发 - 内置函数补充, 反射, 元类,__str__,__del__,exec,type,__call__方法...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。