真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

32面向?qū)ο?_reflection-創(chuàng)新互聯(lián)

目錄

公司主營(yíng)業(yè)務(wù):成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、移動(dòng)網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。成都創(chuàng)新互聯(lián)公司是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來(lái)的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來(lái)驚喜。成都創(chuàng)新互聯(lián)公司推出浮山免費(fèi)做網(wǎng)站回饋大家。

reflection相關(guān)的內(nèi)建函數(shù):...1

反射相關(guān)的魔術(shù)方法(__getattr__()、__setattr__()、__delattr__()):...7

反射相關(guān)的魔術(shù)方法(__getattribute__):...9

reflection反射

指運(yùn)行時(shí),獲取類型定義信息;運(yùn)行時(shí)通過(guò)實(shí)例能查出實(shí)例及所屬類的類型相關(guān)信息;

一個(gè)對(duì)象能夠在運(yùn)行時(shí),像照鏡子一樣,反射出它的所有類型信息;

簡(jiǎn)單說(shuō),在python中,能通過(guò)一個(gè)對(duì)象,找出其type、class、attribute、method的能力,稱為反射或自??;

具有反射能力的函數(shù)有:type()、isinstance()、callable()、dir()、getattr();

注:

運(yùn)行時(shí),區(qū)別于編譯時(shí),指程序被加載到內(nèi)存中執(zhí)行的時(shí)候;

reflection相關(guān)的內(nèi)建函數(shù):

getattr(object,name[,default]),通過(guò)name返回object的屬性值,當(dāng)屬性不存在,將使用default返回,如果沒有default,則拋AttributeError,name必須為字符串;

setattr(object,name,value),object(實(shí)例或類)屬性存在則覆蓋,不存在新增;

hasattr(object,name),判斷對(duì)象是否有這個(gè)名字的屬性,name必須為字符串;

動(dòng)態(tài)添加屬性方式,與裝飾器修改一個(gè)類、mixin方式的差異?

動(dòng)態(tài)添加屬性,是運(yùn)行時(shí)改變類或者實(shí)例的方式,因此反射能力具有更大的靈活性;

裝飾器和mixin,在定義時(shí)就決定了;

注:

一般運(yùn)行時(shí)動(dòng)態(tài)增,很少刪;

self.__class__,同type(self);即實(shí)例a.__class__,同type(a);

例:

class Point:

def __init__(self,x,y):

self.x = x

self.y = y

def __str__(self):

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

__repr__ = __str__

def show(self):

print(self.x,self.y)

p = Point(4,5)

print(p.__dict__)

p.__dict__['y'] = 16

print(p.__dict__['y'])?? #通過(guò)實(shí)例的屬性字典__dict__訪問實(shí)例的屬性,本質(zhì)上是利用反射的能力,這種訪問方式不優(yōu)雅,python提供了相關(guān)的內(nèi)置函數(shù)

p.z = 10

print(p.__dict__)

p1 = Point(4,5)

p2 = Point(10,10)

print(repr(p1),repr(p2))

print(p1.__dict__)

setattr(p1,'y',16)

setattr(p1,'z',18)

print(getattr(p1,'__dict__'))

if hasattr(p1,'show'):?? #動(dòng)態(tài)調(diào)用方法

getattr(p1,'show')()

if not hasattr(Point,'add'):?? #源碼中常用此方式

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

print(Point.add)

print(p1.add)

print(p1.add(p2))

輸出:

{'x': 4, 'y': 5}

16

{'x': 4, 'y': 16, 'z': 10}

Point(4,5) Point(10,10)

{'x': 4, 'y': 5}

{'x': 4, 'y': 16, 'z': 18}

4 16

at 0x7f2d82572e18>

of Point(4,16)>

Point(14,26)

例:

class A:

def __init__(self,x):

self.x = x

a = A(5)

setattr(A,'y',10)?? #運(yùn)行時(shí)改變屬性,在類上操作

print(A.__dict__)

print(a.__dict__)

print(getattr(a,'x'))

print(getattr(a,'y'))?? #實(shí)例沒有y,向上找自己類的

# print(getattr(a,'z'))?? #X

print(getattr(a,'z',100))

setattr(a,'y',1000)?? #在實(shí)例上操作

print(A.__dict__)

print(a.__dict__)

# setattr(a,'mtd',lambda self: 1)?? #在實(shí)例上定義方法,看似可以,實(shí)際不行,未綁定self,若要在調(diào)用時(shí)不出錯(cuò),需把實(shí)際名寫上,如a.mtd(a)

# a.mtd()?? #X

# print(a.mtd(a))?? #V

print(a.__dict__)

setattr(A,'mtd',lambda self: 2)?? #在類上定義方法沒問題

print(a.mtd())

print(A.__dict__)

輸出:

{'__module__': '__main__', '__init__': , '__dict__': , '__weakref__': , '__doc__': None, 'y': 10}

{'x': 5}

5

10

100

{'__module__': '__main__', '__init__': , '__dict__': , '__weakref__': , '__doc__': None, 'y': 10}

{'x': 5, 'y': 1000}

{'x': 5}

2

{'__module__': '__main__', '__init__': , '__dict__': , '__weakref__': , '__doc__': None, 'mtd': at 0x7fde274bfe18>}

習(xí)題:

命令分發(fā)器,通過(guò)名稱找對(duì)應(yīng)的函數(shù)執(zhí)行;

思路:名稱找對(duì)象的方法;

函數(shù)方式實(shí)現(xiàn):

方1:

def dispatcher():

cmds = {}

def reg(cmd,fn):

if isinstance(cmd,str):

cmds[cmd] = fn

else:

print('error')

def run():

???while True:

cmd = input('plz input command: ')

if cmd.strip() == 'quit':

return

print(cmds.get(cmd.strip(),defaultfn)())

def defaultfn():

return 'default function'

return reg,run

reg,run = dispatcher()

reg('cmd1',lambda : 1)

reg('cmd2',lambda : 2)

run()

輸出:

plz input command: cmd3

default function

plz input command:? cmd2

2

plz input command: cmd1

1

plz input command: quit

方2:

def cmds_dispatcher():

cmds = {}

def reg(name):

def wrapper(fn):

cmds[name] = fn

return fn

return wrapper

def dispatcher():

while True:

cmd = input('plz input comd: ')

if cmd.strip() == 'quit':

return

print(cmds.get(cmd.strip(),defaultfn)())

def defaultfn():

return 'default function'

return reg,dispatcher

reg,dispatcher = cmds_dispatcher()

@reg('cmd1')

def foo1():

return 1

@reg('cmd2')

def foo2():

return 2

dispatcher()

面向?qū)ο蠓绞綄?shí)現(xiàn):

使用setattr()和getattr()找到對(duì)象的屬性(實(shí)際是在類上加的,實(shí)例找不到逐級(jí)往上找),比自己維護(hù)一個(gè)dict來(lái)建立名稱和函數(shù)之間的關(guān)系要好;

實(shí)現(xiàn)1:

class Dispatcher:

def cmd1(self):

return 1

def reg(self,cmd,fn):

if isinstance(cmd,str):

setattr(self.__class__,cmd,fn)?? #放在類上最方便,self.__class__同type(self);不要在實(shí)例上定義,如果在實(shí)例上,setattr(self,cmd,fn),調(diào)用時(shí)要注意dis.reg('cmd2',lambda : 2)

else:

print('error')

def run(self):

while True:

cmd = input('plz input cmd: ')

if cmd.strip() == 'quit':

return

print(getattr(self,cmd.strip(),self.defaultfn)())

def defaultfn(self):

return 'default function'

dis = Dispatcher()

dis.reg('cmd2',lambda self: 2)

dis.run()

# print(dis.__class__.__dict__)

# print(dis.__dict__)

輸出:

plz input cmd: cmd1

1

plz input cmd: cmd2

2

plz input cmd: cmd3

default function

plz input cmd: 11

default function

實(shí)現(xiàn)2:

class Dispatcher:

def __init__(self):

self._run()

def cmd1(self):

return 1

def cmd2(self):

return 2

def reg(self,cmd,fn):

if isinstance(cmd,str):

setattr(self.__class__,cmd,fn)

else:

print('error')

def _run(self):

while True:

cmd = input('plz input cmd: ')

if cmd.strip() == 'quit':

return

print(getattr(self,cmd.strip(),self.defaultfn)())

def defaultfn(self):

return 'default function'

Dispatcher()

輸出:

plz input cmd: cmd1

1

plz input cmd: cmd2

2

plz input cmd: cmd3

default function

plz input cmd: abcd

default function

反射相關(guān)的魔術(shù)方法(__getattr__()、__setattr__()、__delattr__()):

__getattr__(),當(dāng)在實(shí)例、實(shí)例的類及祖先類中查不到屬性,才調(diào)用此方法;

__setattr__(),通過(guò)點(diǎn)訪問屬性,進(jìn)行增加、修改都要調(diào)用此方法;

__delattr__(),當(dāng)通過(guò)實(shí)例來(lái)刪除屬性時(shí)調(diào)用此方法,刪自己有的屬性;

一個(gè)類的屬性會(huì)按照繼承關(guān)系找,如果找不到,就是執(zhí)行__getattr__(),如果沒有這個(gè)方法,拋AttributeError;

查找屬性順序?yàn)椋?/p>

instance.__dict__-->instance.__class__.__dict__-->繼承的祖先類直到object的__dict__-->調(diào)用__getattr__(),如果沒有__getattr__()則拋AttributeError異常;

__setattr__()和__delattr__(),只要有相應(yīng)的操作(如初始化時(shí)self.x = x或運(yùn)行時(shí)a.y = 200觸發(fā)__setattr__(),del a.m則觸發(fā)__delattr__())就會(huì)觸發(fā),做攔截用,攔截做增加或修改,屬性要加到__dict__中,要自己完成;

這三個(gè)魔術(shù)方法的第一個(gè)參數(shù)為self,則如果用類名.屬性操作時(shí),則這三個(gè)魔術(shù)方法管不著;

例:

class A:

m = 6

def __init__(self,x):

self.x = x

def __getattr__(self, item):?? #對(duì)象的屬性按搜索順序逐級(jí)找,找到祖先類object上也沒有對(duì)應(yīng)屬性,則最后找__getattr__(),如有定義__getattr__()返回該函數(shù)返回值,如果沒有此方法,則報(bào)錯(cuò)AttributeError: 'A' object has no attribute 'y'

print('__getattr__',item)

print(A(10).x)

print(A(8).y)

輸出:

10

__getattr__ y

None

例:

class A:

m = 6

def __init__(self,x):

self.x = x?? #__init__()中的self.x = x也調(diào)用__setattr__()

def __getattr__(self, item):

print('__getattr__',item)

# self.__dict__[item] = 'default_value'

def __setattr__(self, key, value):

print('__setattr__',key,value)

# self.__dict__[key] = value

def __delattr__(self, item):

print('__delattr__')

a = A(8)?? #初始化時(shí)的self.x = x也調(diào)用__setattr__()

a.x?? #調(diào)用__getattr__()

a.x = 100 ??#調(diào)用__setattr__(),實(shí)例的__dict__為空沒有x屬性,雖有觸發(fā)__setattr__(),但沒寫到__dict__中,要自己寫

a.x

a.y

a.y = 200

a.y

print(a.__dict__)?? #__getattr__()和__setattr__()都有,實(shí)例的__dict__為空,用a.x訪問屬性時(shí)按順序都沒找到最終調(diào)用__getattr__()

print(A.__dict__)

del a.m

輸出:

__setattr__ x 8

__getattr__ x

__setattr__ x 100

__getattr__ x

__getattr__ y

__setattr__ y 200

__getattr__ y

{}

{'__module__': '__main__', 'm': 6, '__init__': , '__getattr__': , '__setattr__': , '__dict__': , '__weakref__': , '__doc__': None}

__delattr__

反射相關(guān)的魔術(shù)方法(__getattribute__):

__getattribute__(),實(shí)例所有屬性調(diào)用,都從這個(gè)方法開始;

實(shí)例的所有屬性訪問,第一個(gè)都會(huì)調(diào)用__getattribute__()方法,它阻止了屬性的查找,該方法應(yīng)該返回(計(jì)算后的)值或拋AttributeError,它的return值將作為屬性查找的結(jié)果,如果拋AttributeError則直接調(diào)用__getattr__(),表示屬性沒有找到;

為了避免在該方法中無(wú)限的遞歸,它的實(shí)現(xiàn)應(yīng)該永遠(yuǎn)調(diào)用基類的同名方法以訪問需要的任何屬性,如object.__getattribute__(self,name);

除非明確知道__getattribute__()方法用來(lái)做什么,否則不要使用它,攔截面太大;

屬性查找順序:

實(shí)例調(diào)用__getattribute__()-->instance.__dict__-->instance.__class__.__dict__-->繼承的祖先類直到object的__dict__-->調(diào)用__getattr__();

例:

class A:

m = 6

def __init__(self,x):

self.x = x

def __getattr__(self, item):

print('__getattr__',item)

# self.__dict__[item] = 'default_value'

def __setattr__(self, key, value):

print('__setattr__',key,value)

# self.__dict__[key] = value

def __delattr__(self, item):

print('__delattr__')

def __getattribute__(self, item):

print('__getattribute__',item)

raise AttributeError(item)?? #如果拋AttributeError則直接調(diào)用__getattr__(),表示屬性沒找到

# return self.__dict__[item]?? #遞歸調(diào)用

# return object.__getattribute__(self,item) ??#繼續(xù)向后找,這樣做沒意義

a = A(8)

a.x

a.y

a.z

輸出:

__setattr__ x 8

__getattribute__ x

__getattr__ x

__getattribute__ y

__getattr__ y

__getattribute__ z

__getattr__ z

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)cdcxhl.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。


分享題目:32面向?qū)ο?_reflection-創(chuàng)新互聯(lián)
標(biāo)題URL:http://weahome.cn/article/digjpp.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部