day7面向對象--反射

来源:http://www.cnblogs.com/gengcx/archive/2017/07/30/7258299.html
-Advertisement-
Play Games

反射 通過字元串映射或修改程式運行時的狀態、屬性、方法, 有以下4個方法 1、getattr(object, name[, default]) -> value Get a named attribute from an object; getattr(x, 'y') is equivalent t ...


反射

    通過字元串映射或修改程式運行時的狀態、屬性、方法, 有以下4個方法

    1、getattr(object, name[, default]) -> value

    Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
    When a default argument is given, it is returned when the attribute doesn't
    exist; without it, an exception is raised in that case.

    判斷類中是否有指定的方法,如下:

class Dog(object):

    def __init__(self,name):
        self.name = name

    def eat(self):
        print("%s is eating......" %self.name)

d = Dog("alex")
choice = input(">>:").strip()    #用戶輸入函數,判斷函數是否存在,存在執行,反射來判斷執行
print(hasattr(d,choice))
運行如下:
>>:talk
False
>>:eat
True

    我們知道,有時候我們要根據用戶輸入來判斷類中是否有某種方法,這樣我們就能執行了。如何去判斷呢?可以使用hasattr(object,name)方法。上面,我們實現了動態判斷方法,如果存在返回True,否則返回False。

    2、getattr(object, name[, default]) -> value
    Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
    When a default argument is given, it is returned when the attribute doesn't
    exist; without it, an exception is raised in that case.

class Dog(object):

    def __init__(self,name):
        self.name = name

    def eat(self):
        print("%s is eating......" %self.name)

d = Dog("alex")
choice = input(">>:").strip()    #用戶輸入函數,判斷函數是否存在,存在執行,反射來判斷執行
print(getattr(d,choice))
運行結果如下:
>>:tall
Traceback (most recent call last):
  File "/home/zhuzhu/第七天/get_attr.py", line 11, in <module>
    print(getattr(d,choice))
AttributeError: 'Dog' object has no attribute 'tall'
>>:eat
<bound method Dog.eat of <__main__.Dog object at 0x7fecf92428d0>>

    從上面可以看出,getattr()是獲取屬性的記憶體地址,如果存在返回記憶體地址,如果不存在,則返回錯誤,提示類中不存在這個方法。

    既然getattr()存在放回方法的記憶體地址,那麼加上括弧執行一下,如下:

class Dog(object):

    def __init__(self,name):
        self.name = name

    def eat(self):
        print("%s is eating......" %self.name)

d = Dog("alex")
choice = input(">>:").strip()    #用戶輸入函數,判斷函數是否存在,存在執行,反射來判斷執行
getattr(d,choice)()
運行結果如下:
>>:eat
alex is eating......

    從上面可以看出,程式正常執行了,通過上面,我們可以發現,hasattr()和getattr()經常結合一起使用,hasattr()判斷是否有這個方法,而getattr()用來執行。如果存在,則調用getattr()進行執行。如下:

class Dog(object):

    def __init__(self,name):
        self.name = name

    def eat(self):
        print("%s is eating......" %self.name)

d = Dog("alex")
choice = input(">>:").strip()    #用戶輸入函數,判斷函數是否存在,存在執行,反射來判斷執行
if hasattr(d,choice):
    '''這種場景在很多情況下都使用,比如讓用戶輸入某個功能,如果存在執行,不存在則告訴用戶沒有這個功能'''
    getattr(d,choice)()

else:
    print("您輸入的方法不存在,請核對後重新輸入:")
運行結果如下:
>>:eat #存在執行方法
alex is eating......
>>:tall #不存在,提示方法沒有
您輸入的方法不存在,請核對後重新輸入

    從上面代碼可以看出,能夠實現動態用戶輸入判斷方法是否存在,存在執行,不存在提示的功能。

    下麵是實現帶參數的情況:

class Dog(object):

    def __init__(self,name):
        self.name = name

    def eat(self,food):
        print("%s is eating......%s" %(self.name,food))

d = Dog("alex")
choice = input(">>:").strip()    #用戶輸入函數,判斷函數是否存在,存在執行,反射來判斷執行
if hasattr(d,choice):
    '''這種場景在很多情況下都使用,比如讓用戶輸入某個功能,如果存在執行,不存在則告訴用戶沒有這個功能'''
    func = getattr(d,choice)
    func("chenronghua")
    #getattr(d,choice)("chenronghua")

else:
    print("您輸入的方法不存在,請核對後重新輸入:")
運行結果如下:
>>:eat
alex is eating......chenronghua

   也可以判斷屬性是否存在,如下,就判斷裡面單純的屬性,得到屬性值:

class Dog(object):

    def __init__(self,name):
        self.name = name

    def eat(self,food):
        print("%s is eating......%s" %(self.name,food))

d = Dog("alex")
choice = input(">>:").strip()    #用戶輸入函數,判斷函數是否存在,存在執行,反射來判斷執行
if hasattr(d,choice):
    '''這種場景在很多情況下都使用,比如讓用戶輸入某個功能,如果存在執行,不存在則告訴用戶沒有這個功能'''
    func = getattr(d,choice)
    print(func)
    # func("chenronghua")
    #getattr(d,choice)("chenronghua")

else:
    print("您輸入的方法不存在,請核對後重新輸入:")
運行結果如下:
>>:name
alex

    3.setattr(obj, name, value, /)
    Sets the named attribute on the given object to the specified value.
    
    setattr(x, 'y', v) is equivalent to ``x.y = v''
    添加動態屬性:

class Dog(object):

    def __init__(self,name):
        self.name = name

    def eat(self,food):
        print("%s is eating......%s" %(self.name,food))

def talk(self):
    print("%s is talking....." %self.name)

def laugh(self):
    print("%s is laughing....." %self)

d = Dog("alex")
choice = input(">>:").strip()    #用戶輸入函數,判斷函數是否存在,存在執行,反射來判斷執行
if hasattr(d,choice):
    '''這種場景在很多情況下都使用,比如讓用戶輸入某個功能,如果存在執行,不存在則告訴用戶沒有這個功能'''
    func = getattr(d,choice)
    print(func)
    # func("chenronghua")
    #getattr(d,choice)("chenronghua")

else:
    #setattr(d,choice,laugh)     #動態添加一個屬性
    setattr(d,"alex","sb")      #動態加入一個屬性
    print(getattr(d,"alex"))
運行結果如下:
>>:alex
sb

    添加動態方法:

class Dog(object):

    def __init__(self,name):
        self.name = name

    def eat(self,food):
        print("%s is eating......%s" %(self.name,food))

def talk(name):
    print("%s is talking....." %name)

def laugh(self):
    print("%s is laughing....." %self)

d = Dog("alex")
choice = input(">>:").strip()    #用戶輸入函數,判斷函數是否存在,存在執行,反射來判斷執行
if hasattr(d,choice):
    '''這種場景在很多情況下都使用,比如讓用戶輸入某個功能,如果存在執行,不存在則告訴用戶沒有這個功能'''
    func = getattr(d,choice)
    print(func)
    # func("chenronghua")
    #getattr(d,choice)("chenronghua")

else:
    setattr(d,choice,laugh)     #動態添加一個屬性
    #setattr(d,"alex","sb")      #動態加入一個屬性
    print(getattr(d,choice)("alex"))

    其實,setattr(obj,name_str,屬性/方法)就是把一個屬性/方法賦值給name_str,如果第三參數是一個方法,那麼就賦值了一個方法給name_str,如果第三參數是一個屬性,那麼就賦值一個屬性給name_str,是屬性,使用getattr(obj,name_str)得到的是一個字元串;是方法,使用get(obj,name_str)得到的是一個方法的記憶體地址,其實本質還是上面的getattr(),方法就要看是否有參數,有參數就加入參數調用執行,沒有參數就直接加括弧執行。

    4.delattr(obj, name, /)
    Deletes the named attribute from the given object.
    
    delattr(x, 'y') is equivalent to ``del x.y''

class Dog(object):

    def __init__(self,name):
        self.name = name

    def eat(self,food):
        print("%s is eating......%s" %(self.name,food))

def talk(name):
    print("%s is talking....." %name)

def laugh(self):
    print("%s is laughing....." %self)

d = Dog("alex")
choice = input(">>:").strip()    #用戶輸入函數,判斷函數是否存在,存在執行,反射來判斷執行
if hasattr(d,choice):
    '''這種場景在很多情況下都使用,比如讓用戶輸入某個功能,如果存在執行,不存在則告訴用戶沒有這個功能'''
    func = getattr(d,choice)
    print(func)
    # func("chenronghua")
    #getattr(d,choice)("chenronghua")

else:
    setattr(d,choice,laugh)     #動態添加一個屬性
    #setattr(d,"alex","sb")      #動態加入一個屬性
    getattr(d,choice)("alex")
    delattr(d,choice)            #刪除屬性或者方法
    getattr(d, choice)("alex")

    delattr(obj,name_str)刪除實例中的方法或者屬性。

    反射:

        hasattr(obj,attr),判斷一個對象里是否有對應的字元串的方法

        getattr(obj,name_str),根據字元串去獲取obj對象里對應的方法的記憶體地址。

        setattr(obj,name_str,z)等價於obj.name_str = z

        delattr(obj,name_str)刪除實例彙總的方法或屬性

 

class Dog(object):

    def __init__(self,name):
        self.name = name

    def eat(self,food):
        print("%s is eating......%s" %(self.name,food))

def talk(name):
    print("%s is talking....." %name)

def laugh(self):
    print("%s is laughing....." %self)

d = Dog("alex")
choice = input(">>:").strip()    #用戶輸入函數,判斷函數是否存在,存在執行,反射來判斷執行
set_what = input("把那個變數賦值給屬性:").strip()

if hasattr(d,choice):
    getattr(d,choice)
else:
    setattr(d,choice,laugh)
    v = getattr(d,choice)
    if type(v) == str:
        print(v)
    else:
        print(v("alex"))
運行結果如下:
>>:alex
把那個變數賦值給屬性:sb
alex is laughing.....
None

 

    上面實例是對setattr()的進一步補充,其實就是設置屬性或者方法。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 如果你沒有看我第二天寫的內容的,我想你是看不懂的!!!! 好了,廢話不多說,怎麼才能讓我們的代碼變得牛逼起來呢?怎麼封裝我們的代碼呢?我們不可能 每個頁面都需要那樣寫吧,那我們來一步一步來封裝 我們的代碼,變得更牛逼,維護性更高!!!!! 首先我們來分析,我昨天寫的代碼: 第一步:在界面寫入2個隱藏 ...
  • 問題2: 每次與後臺打交道 都需要寫一些自己都看不太懂的事件,而且傳參數很麻煩,這就是.net 封裝的事件,如何解決呢? 首先不要以為寫webfrom事件,都需要通過 伺服器控制項來綁定後臺的事件,其實說白了綁定的事件其實都是form表單提交,而且還都是id為form1的表單提交。 如果你不知道這些, ...
  • 修飾符 應用於 說明 public 所有類型或成員 任何代碼都可以訪問 protected 類型和內嵌類型的所有成員 只有派生的類型可以訪問 internal 所有類型或成員 只能在包含它的程式集中訪問 private 類型和內嵌類型的所有成員 只能在它所屬的類型中訪問 protected inte... ...
  • 1 public class Program1 2 { 3 #region 結構 4 //結構是值類型,存儲在棧上 5 //1:結構中的成員變數不能有初始值 6 //2:結構中不能聲明無參數構造函數 7 struct Example 8 { 9 //public int Width = 1;//錯誤 ...
  • 1 class Program 2 { 3 //數組是引用類型 4 //如果把數組或類等其他引用類型傳遞給方法,對應的方法就會使用該引用類型改編數組中值, 5 //而新值會反射到原始數組上 6 static void SomeFunction(int[] ints, int i) 7 { 8 int ...
  • 1、前言 surging受到不少.net同學的青睞,也提了不少問題,提的最多的是什麼時候集成API 網關,在這裡回答大家最近已經開始著手研發,應該在1,2個月內會有個初版API網關,其它像Token身份驗證,限流降級等功能完成時間會往後推 最近也更新了surging新的版本 更新內容: 1. Cac ...
  • 一.什麼是ORM 對象關係映射(Object Relational Mapping,簡稱ORM)模式是一種為瞭解決面向對象與關係資料庫存在的互不匹配的現象的技術。 簡單來說,ORM 是通過使用描述對象和資料庫之間映射的元數據,將程式中的對象自動持久化到關係資料庫中或者將資料庫的數據拉取出來 二.EF ...
  • 前言 工作中經常會寫一些重覆的代碼片段,如自動屬性、for迴圈、Action等等,針對這種情況,VisualStudio已經給我們提供了一個非常方便的功能——代碼片段,是我們可以簡單的輸入幾個字母就能生成大段代碼。 但是,工作中總會遇到一些重覆代碼是VisualStudio沒有提供的,這時就需要我們 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...