1. 程式人生 > >內置函數補充,__str__方法、__del__方法 和 __call__方法和元祖

內置函數補充,__str__方法、__del__方法 和 __call__方法和元祖

方式 mysql peer 自動調用 title error 實例化 首字母 utf

一 、內置函數補充

1.isinstance函數:
isinstance(obj,cls)檢查obj是否是類 cls 的對象
使用該函數來判斷一個函數的類型

2. issubclass(sub, super)檢查sub類是否是 super 類的派生類

class Foo(object):
pass
class Bar(Foo):
pass
issubclass(Bar, Foo)

3.下述四個函數是專門用來操作類與對象屬性的,如何操作?
通過字符串來操作類與對象的屬性,這種操作稱為反射
class People:
country="China"
def __init__(self,name):
self.name=name
def tell(self):
print(‘%s is aaa‘ %self.name)

obj=People(‘egon‘)
1、hasattr #檢測是否含有某屬性
print(hasattr(obj,‘name‘))
print(hasattr(obj,‘country‘))
print(hasattr(obj,‘tell‘))

2、getattr #獲取對應的屬性
f=getattr(obj,‘tell‘,None) # None為沒有對應屬性是的默認返回值
print(f == obj.tell)
f()
obj.tell()

3、setattr #設置屬性等同修改操作
obj.age=18
setattr(obj,"age",18)
print(obj.__dict__)

4、delattr #刪除屬性
del obj.name
delattr(obj,"name")
print(obj.__dict__)

二、__str__方法、__del__方法 和 __call__方法

1. __str__是系統默認函數,在打印對象時自動觸發函數執行

class People:
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex

def __str__(self):
# print(‘========>‘)
return ‘<名字:%s 年齡:%s 性別:%s>‘ %(self.name,self.age,self.sex)

obj=People(‘egon‘,18,‘male‘)
print(obj)
2. __del__也是系統默認函數在程序結束時,對象被刪除的條件下,自動執行。
註:如果產生的對象僅僅只是python程序級別的(用戶級),那麽無需定義__del__,如果產生的
對象的同時還會向操作系統發起系統調用,即一個對象有用戶級與內核級兩種資源,比如(打開
一個文件,創建一個數據庫鏈接),則必須在清除對象的同時回收系統資源3,這就用到了__del__。

實際使用示例:
class MyOpen:
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)
return msg

def __del__(self):
self.fobj.close() #此時在清除對象之前自動執行歸還系統資源

res=f.fobj.read()
print(res)

3.__call__ :對象後面加括號,觸發執行。
構造方法的執行是由創建對象觸發的,即:對象 = 類名() ;而對於 __call__
方法的執行是由對象後加括號觸發的,即:對象() 或者 類()()
class Foo:
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()

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


三、元類

1. 一切皆為對象:
元類:類的類就是元類,
我們用class定義的類使用來產生我們自己的對象的
內置元類type是用來專門產生class定義的類的

2、用內置的元類type,來實例化得到我們的類
class_name=‘Chinese‘
class_bases=(object,)
class_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)
# 類的三大要素class_name,class_bases,class_dic

3 、自定義元類: 自己可以控制類規範
class Mymeta(type):
# 來控制類Foo的創建
def __init__(self,class_name,class_bases,class_dic): #self=Foo
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={}
#1 造一個空對象obj
obj=object.__new__(self)
#2、調用Foo.__init__,將obj連同調用Foo括號內的參數一同傳給__init__
self.__init__(obj,*args,**kwargs)
return obj

# 下一行等同於傳值 Foo=Mymeta(‘Foo‘,(object,),class_dic)
class Foo(object,metaclass=Mymeta):
"""
文檔註釋
"""
x=1
def __init__(self,y):
self.Y=y

def f1(self):
print(‘from f1‘)

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

5.單例模式:適用於值重復不會改變,可節省一定資源

方式一、
import settings

class MySQL:
__instance=None
def __init__(self,ip,port):
self.ip=ip
self.port=port

@classmethod
def singleton(cls):
if not cls.__instance:
obj=cls(settings.IP, settings.PORT)
cls.__instance=obj
return cls.__instance

obj4=MySQL.singleton()
obj5=MySQL.singleton()
obj6=MySQL.singleton()

print(obj4 is obj5 is obj6)

內置函數補充,__str__方法、__del__方法 和 __call__方法和元祖