Python中的反射

什么是反射

反射主要是指程序可以訪問、檢測和修改它本身狀態或行為的一種能力(自省)。
python面向對象中的反射就是通過字符串獲取對象或者類的屬性,進行操作~,主要是對這4個方法的應用:hasattr,getattr,setattr,delattr。

網站建設哪家好,找成都創新互聯公司!專注于網頁設計、網站建設、微信開發、重慶小程序開發、集團企業網站建設等服務項目。為回饋新老客戶創新互聯還提供了松北免費建站歡迎大家使用!

反射對象的屬性和方法

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,執行反射獲取的方法
name = getattr(p, '_Person__name')
print(name)    # baby
# 若是屬性不存在則報錯
# age = getattr(p, 'age')   # 'Person' object has no attribute 'age'

# 設置屬性
setattr(p, 'sex', 'male')       # 設置的是對象的屬性,存放在對象的名稱空間中
# 這里設置的方法是普通方法,存放在對象的名稱空間中,self.__name不會變形為 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))    # 不是綁定方法,需要手動傳值

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

Tip:

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

反射類的屬性和方法

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 屬于對象
print(hasattr(Person, 'say'))                       # True

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

# 設置屬性
setattr(Person, 'sex', 'male')    # 設置的是類的靜態屬性
setattr(Person, 'show_city', lambda self: self.city)   # 這里通過類設置的方法為綁定到對象的方法,通過對象調用的時候能夠自動傳值(self)
print(p.show_city())    # NB
# setattr(Person, 'show_name', lambda self: self.__name)   # self.__name 不會自動轉換為 self._Person__name
# print(p.show_name())    # AttributeError: 'Person' object has no attribute '__name'

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

# 獲取類方法
getattr(Person, 'play')()   # 會完成自動傳值,默認將Person作為第一個參數傳遞給play方法

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

Tip:

  • 通過類設置的屬性,存放在類的名稱空間中;
  • 通過類設置的方法為綁定到對象的方法,通過對象調用的時候,能夠完成自動傳值;同樣方法內無法訪問到私有變量(self.__屬性 不會自動轉換為self._類名__屬性)

反射當前模塊成員

import sys

def s1():
    print('s1')

def s2():
    print('s2')

this_module = sys.modules[__name__]

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

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

sys.modules[__name__] 也可以寫成 sys.modules['__main__'],但是不建議這么寫,因為當前的模塊被導入到另外一個模塊的時候,這個被導入的模塊使用 sys.modules['__main__'] 就獲取不到它的內存地址了~
 
操作的對象也可以是導入的模塊

# 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 方法用來判斷 一個對象 和 一個類之間的關系,即這個對象是不是由這個類實例化而來

class Person:
    pass

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

 
issubclass 用來判斷兩個類之間是否存在繼承關系

class Father:
    pass

class Son(Father):
    pass

print(issubclass(Son, Father))    # True

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

當前標題:Python中的反射
文章網址:http://m.kartarina.com/article38/jedgsp.html

成都網站建設公司_創新互聯,為您提供網站營銷企業建站搜索引擎優化App開發全網營銷推廣

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

網站建設網站維護公司
主站蜘蛛池模板: 无码乱码av天堂一区二区| 久久久久亚洲AV片无码下载蜜桃| 亚洲av激情无码专区在线播放| 亚洲午夜无码久久久久小说| 亚洲AV无码专区在线观看成人 | 久久精品无码专区免费东京热| 亚洲AV无码国产在丝袜线观看| 久久综合精品国产二区无码| 人妻丰满?V无码久久不卡| 无码精品人妻一区| 少妇精品无码一区二区三区| 夜夜精品无码一区二区三区 | 在线精品免费视频无码的| 免费人妻无码不卡中文字幕系| 国产精品第一区揄拍无码| 亚洲成A∨人片在线观看无码| 亚洲成AV人片在线播放无码| 成年男人裸j照无遮挡无码| 亚洲国产精品无码久久久蜜芽| 精品无码成人片一区二区| 亚洲AV无码成人精品区日韩| 久久国产精品无码一区二区三区| 天堂Aⅴ无码一区二区三区| 国产AV天堂无码一区二区三区| 久久久久亚洲AV无码网站| 午夜无码伦费影视在线观看| 久久无码AV中文出轨人妻| 久久亚洲国产成人精品无码区| 无码福利写真片视频在线播放| 亚洲中文字幕不卡无码| 国产AV无码专区亚洲A∨毛片| 亚洲熟妇少妇任你躁在线观看无码| 无码免费午夜福利片在线| 亚洲AV无码国产精品永久一区| 久久无码专区国产精品发布| av无码人妻一区二区三区牛牛| 免费无码作爱视频| 久久影院午夜理论片无码| 熟妇人妻中文av无码| 四虎影视无码永久免费| 久久亚洲精品无码播放|