魔術方法反射

2021-09-23 20:25:22 字數 3769 閱讀 9748

反射

執行時,區別於編譯時,指的是程式被載入到記憶體中執行的時候。

反射,reflection,指的是執行時獲取型別定義資訊。

乙個物件能夠在執行時,像照鏡子一樣,反射出其型別資訊。

簡單說,在python中,能夠通過乙個物件,找出其type、class、attribute或method的能力,稱為反射或者自 省。

具有反射能力的函式有 type()、isinstance()、callable()、dir()、getattr()等

反射相關的函式和方法

需求內建函式

意義getattr(object,name[,default])

通過name返回object的屬性值,當屬性不存在,將使用default返回,如果沒有default,則丟擲attributeerror.name必須為字串

setattr(object,name,value)

object的屬性存在,則覆蓋,不存在,新增

hasattr(object,name)

判斷物件是否有這個名字的屬性,name必須為字串

class point:

def __init__(self,x,y):

self.x = x

self.y = y

def __str__(self):

return '{},{}'.format(self.x,self.y)

def show(self):

print(self.x,self.y)

p = point(3,4)

p2 = point(5,6)

print(getattr(p,'z',1000))

#動態增加方法

#為類增加方法

if not hasattr(point,'add'):

setattr(point,'add',lambda self,other:point(self.x+other.x,self.y+other.y))

print(p.add(p2))#繫結

#為例項增加方法,未繫結

if not hasattr(p,'sub'):

setattr(p,'sub',lambda self,other:point(self.x-other.x,self.y-other.y))

print(p.sub(p2,p))

print(point.__dict__)

print(p.__dict__)

這種動態增刪屬性的方式是執行時改變類或者例項的方式,但是裝飾器或mixin都是定義時就決定了,因此反射能力具有更大的靈活性.

反射相關的魔術方法

__getattr__(),__setattr__(),__delattr__()這三個魔術方法,分別測試者三個方法

class base:

n = 0

class point(base):

z = 6

def __init__(self,x,y):

self.x = x

self.y = y

def show(self):

print(self.x,self.y)

def __getattribute__(self,item):

return object.__getattribute__(self,item)

def __getattr__(self,item):

return item

def __setattr__(self,key,value):

print('{}{}'.format(key,value))

self.__dict__[key] = value

p = point(1,2)

print(p.x)

print(p.y)

print(p.__dict__)

print(p.z)

__getattr__()

例項屬性會按照繼承關係找,如果找不到,就會執行__getattr__()方法,如果沒有這個方法,就會丟擲attributeerror異常表示找不到屬性

查詢屬性順序為:

instance.__dict__ --> instance.__class__.__dict__ --> 繼承的祖先類(直到object)的__dict__ —找不到–> 調 用__getattr__()

__setattr__()

例項通過.點號設定屬性,例如self.x = x屬性賦值,就會呼叫__setattr__(),屬性要加到例項的__dict__中,就需要自己完成

__setattr__()方法,可以攔截對例項屬性的增加 修改操作,如果要設定生效,需要自己操作例項的__dict__

__delattr__()

class point():

z = 6

def __init__(self,x,y):

self.x = x

self.y = y

def __delattr__(self,item):

print(item)

p = point(1,2)

p.z = 10

del p.z

print(p.__dict__)

print(point.__dict__)

del point.z

print(point.__dict__)

可以阻止通過例項來刪除屬性的操作,但是通過類依然可以刪除屬性

__getattribute__

例項的所有的屬性訪問,第乙個都會呼叫__getattribute__方法,它阻止了屬性的查詢,該方法應該返回(計算後的值)或者丟擲乙個atteributeerror異常

class base:

n = 0

class point(base):

z = 6

def __init__(self,x,y):

self.x = x

self.y = y

def __getattribute__(self,item):

return object.__getattribute__(self,item)

def __getattr__(self,item):

return item

p = point(1,2)

print(p.x)

print(p.y)

print(p.__dict__)

print(p.z)

__getattribute__方法中為了避免在該方法中無限的遞迴,它的實現應該永遠呼叫基類的同名方法以訪問需要的任何屬性,例如object.__getattribute__(self,item)

注意,除非你明確地知道 __getattribute__ 方法用來做什麼,否則不要使用它

魔術方法

意義__getattr__()

當通過搜尋例項、例項的類及祖先類查不到屬性,就會呼叫此方法

__setattr__()

通過 . 訪問例項屬性,進行增加、修改都要呼叫它

__delattr__

當通過例項來刪除屬性時呼叫此方法

__getattribute__

例項所有的屬性呼叫都從這個方法開始

屬性查詢順序

例項呼叫__getattribute__() --> instance.__dict__ --> instance.__class__.__dict__ --> 繼承的祖先類(直到 object)的__dict__ --> 呼叫__getattr__()

with 魔術方法

with open demo1.py as fp print fp.read enter self exit enter 魔術方法 使用with語句的時候,會呼叫這個魔術方法 這個方法的返回值可以作為as x的值 exit self,exc type,exc val,exc tb 魔術方法 1.執行...

php魔術常量,魔術方法

魔術常量 1。line 返回檔案中的當前行號。2。file 返回檔案的完整路徑和檔名。如果用在包含檔案中,則返回包含檔名。自php4.0.2 起,file 總是包含乙個絕對路徑,而在此之前的版本有時會包含乙個相對路徑。3。function 返回函式名稱 php4.3.0 新加 自php5 起本常量返...

invoke 魔術 PHP 魔術方法

php 魔術方法 構造方法 construct 析構方法 destruct get 與 set unset call 和 callstatic sleep 和 wakeup clone tostring invoke set state debuginfo construct 這個方法應該是最常用的...