溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Python中的反射

發(fā)布時(shí)間:2020-08-05 13:16:38 來源:網(wǎng)絡(luò) 閱讀:675 作者:LJ_baby 欄目:編程語言

什么是反射

反射主要是指程序可以訪問、檢測(cè)和修改它本身狀態(tài)或行為的一種能力(自?。?br/>python面向?qū)ο笾械姆瓷渚褪峭ㄟ^字符串獲取對(duì)象或者類的屬性,進(jìn)行操作~,主要是對(duì)這4個(gè)方法的應(yīng)用:hasattr,getattr,setattr,delattr。

反射對(duì)象的屬性和方法

class Person:
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

    def __fun(self):
        print(self.__class__)

    def say(self):
        print(self.__name + ' ' + str(self.__age))

# 判斷屬性是否存在
p = Person('baby', 18)
print(hasattr(p, 'name'))                    # False
print(hasattr(p, '_Person__name'))   # True
print(hasattr(p, 'say'))                       # True

# 獲取屬性
fun = getattr(p, 'say')
fun()                # baby 18,執(zhí)行反射獲取的方法
name = getattr(p, '_Person__name')
print(name)    # baby
# 若是屬性不存在則報(bào)錯(cuò)
# age = getattr(p, 'age')   # 'Person' object has no attribute 'age'

# 設(shè)置屬性
setattr(p, 'sex', 'male')       # 設(shè)置的是對(duì)象的屬性,存放在對(duì)象的名稱空間中
# 這里設(shè)置的方法是普通方法,存放在對(duì)象的名稱空間中,self.__name不會(huì)變形為 self._Person__name
# setattr(p, 'show_name', lambda self: self.__name)   
setattr(p, 'say_hello', lambda self: 'Hello ' + self._Person__name)
print(p.__dict__)         
# {'_Person__name': 'baby', '_Person__age': 18, 'sex': 'male', 'say_hello': <function <lambda> at 0x10f7bf2f0>}
print(p.say_hello(p))    # 不是綁定方法,需要手動(dòng)傳值

# 刪除屬性
delattr(p, 'sex')
print(p.__dict__)
# {'_Person__name': 'baby', '_Person__age': 18, 'say_hello': <function <lambda> at 0x10f7bf2f0>}
# 若不存在該屬性則報(bào)錯(cuò)
# delattr(p, 'name')     # AttributeError: name

Tip:

  • 通過對(duì)象設(shè)置的屬性,不管是變量還是方法,都存放在對(duì)象的名稱空間中;
  • 通過對(duì)象設(shè)置的方法僅僅是普通方法,調(diào)用的時(shí)候也不會(huì)自動(dòng)傳值(需要手動(dòng)傳值),且方法中不能使用對(duì)象的私有屬性

反射類的屬性和方法

class Person:
    def __init__(self, name, age):
        self.__name = name
        self.__age = age
        self.city = 'NB'

    def __fun(self):
        print(self.__class__)

    def say(self):
        print(self.__name + ' ' + str(self.__age))

    @classmethod
    def play(cls):
        print(cls.__name__)

    @staticmethod
    def sleep():
        print('sleep...')

# 判斷屬性是否存在
print(hasattr(Person, 'name'))                    # False
print(hasattr(Person, '_Person__name'))   # False,私有屬性 __name,__age 屬于對(duì)象
print(hasattr(Person, 'say'))                       # True

# 獲取屬性
fun = getattr(Person, 'say')
p = Person('baby', 18)
fun(p)          # baby 18,等同于Person.say(p),需要手動(dòng)傳遞self
# 若是屬性不存在
# age = getattr(Person, 'age')   # 報(bào)錯(cuò),'Person' object has no attribute 'age'

# 設(shè)置屬性
setattr(Person, 'sex', 'male')    # 設(shè)置的是類的靜態(tài)屬性
setattr(Person, 'show_city', lambda self: self.city)   # 這里通過類設(shè)置的方法為綁定到對(duì)象的方法,通過對(duì)象調(diào)用的時(shí)候能夠自動(dòng)傳值(self)
print(p.show_city())    # NB
# setattr(Person, 'show_name', lambda self: self.__name)   # self.__name 不會(huì)自動(dòng)轉(zhuǎn)換為 self._Person__name
# print(p.show_name())    # AttributeError: 'Person' object has no attribute '__name'

# 刪除屬性
delattr(Person, 'sex')   # 刪除的是類的靜態(tài)屬性

# 獲取類方法
getattr(Person, 'play')()   # 會(huì)完成自動(dòng)傳值,默認(rèn)將Person作為第一個(gè)參數(shù)傳遞給play方法

# 獲取靜態(tài)方法
getattr(Person, 'sleep')()

Tip:

  • 通過類設(shè)置的屬性,存放在類的名稱空間中;
  • 通過類設(shè)置的方法為綁定到對(duì)象的方法,通過對(duì)象調(diào)用的時(shí)候,能夠完成自動(dòng)傳值;同樣方法內(nèi)無法訪問到私有變量(self.__屬性 不會(huì)自動(dòng)轉(zhuǎn)換為self._類名__屬性)

反射當(dāng)前模塊成員

import sys

def s1():
    print('s1')

def s2():
    print('s2')

this_module = sys.modules[__name__]

# 判斷模塊中是否存在 s1 方法
print(hasattr(this_module, 's1'))   # True

# 獲取模塊中的方法并執(zhí)行
getattr(this_module, 's2')()           # s2

sys.modules[__name__] 也可以寫成 sys.modules['__main__'],但是不建議這么寫,因?yàn)楫?dāng)前的模塊被導(dǎo)入到另外一個(gè)模塊的時(shí)候,這個(gè)被導(dǎo)入的模塊使用 sys.modules['__main__'] 就獲取不到它的內(nèi)存地址了~
 
操作的對(duì)象也可以是導(dǎo)入的模塊

# module_test

def test():
    print('from test')

# test.py

import module_test

print(hasattr(module_test,'test'))   # True
getattr(module_test, 'test')()          # from test

isinstance 和 issubclass

isinstance 方法用來判斷 一個(gè)對(duì)象 和 一個(gè)類之間的關(guān)系,即這個(gè)對(duì)象是不是由這個(gè)類實(shí)例化而來

class Person:
    pass

p = Person()
print(isinstance(p, Person))    # True

 
issubclass 用來判斷兩個(gè)類之間是否存在繼承關(guān)系

class Father:
    pass

class Son(Father):
    pass

print(issubclass(Son, Father))    # True

.................^_^

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI