1. 程式人生 > >python中的hasattr()、getattr()、setattr()

python中的hasattr()、getattr()、setattr()

lun not mman bject 參數 continue 我想 each trac

hasattr()的用法和理解--hasattr(obj, target)

判斷對象obj中是否含有,目標target屬性,然後返回布爾值,如果有返回True,沒有返回False。

>>> class School:
...     def __init__(self):
...         self.teacher_name = self.teacher
...     def teacher(self): 
...         return input("輸入姓名:")
... 
>>> s1 = School()                   #實例化一個學校對象
>>> hasattr(s1, "teacher")      #查看s對象中是否有teacher屬性(方法)
True                                      #有該屬性返回True
>>> hasattr(s1, "student")
False                                    #s對象中沒有student屬性,返回False
>>> 
getattr()的用法--getattr(obj, target)

使用getattr()函數,可以將對象obj中的屬性、方法獲取出來

>>> class School:
...     def __init__(self):
...         self.teacher_name = self.teacher
...     def teacher(self): 
...         return input("輸入姓名:")
... 
>>> s2 = School()
>>> func = getattr(s2, "teacher")   #獲取s2實例當中的teacher函數,並將其賦值給func
>>> print(func())                            #在這兒調用func函數,等於調用teacher函數
輸入姓名: lina
‘lina‘
>>> 
>>> getattr(s2, "student")              #嘗試獲取一個對象中不存在的方法
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
AttributeError: ‘School‘ object has no attribute ‘student‘                  
 #發生了屬性聲明錯誤,該對象中沒有想要獲得的屬性
#當然為了避免出錯,可以設置一個默認值
>>> getattr(s2, "student", "AttributeError")
‘AttributeError‘
>>> 
setattr()給對象的屬性賦值,如果該屬性不存在,那就先創建在賦值--setattr(obj, name, value)

看到這兒我想都能應該明白怎麽用了,上一個例子中,最後我們嘗試獲取一個不存在的屬性發生錯誤,如果我們先用setattr()方法,那麽就可先向對象中創建該屬性、方法

>>> class School:
...     def __init__(self):
...         self.teacher_name = self.teacher
...     def teacher(self): 
...         return input("輸入姓名:")
... 
>>> 
>>> def student():
...     return input("學生姓名:")
... 
>>> setattr(School, "student", student)          #直接往School類當中設置名字為"student"的方法student也是可以的,
>>>School.student()                                      #現在在School類當中直接調用student()方法就不會報錯了
學生姓名:luna
‘luna‘
>>> s3 = School()
>>> s3.__setattr__("stu", student)                #類中的隱藏函數__setattr__(name, value) 也可以完成設置屬性、方法
>>> s3.stu()
學生姓名:Amber
‘Amber‘
>>>
hasattr()、getattr()思考拓展

很多時候我們面對一個未知的程序,未知的類。也不能去瞎改別人的代碼,而這兩個函數就可以幫助我們測試,加上setattr()就可以直接打補丁,來修改以達到我們目的。
而hasattr()和getattr()更為重要的應用當然還是,關系映射。
都知道類與類之間或者與函數、對象之間,相聯系的方式有繼承、派生和類的組合。而這些方式都需要直接聯系。
而hasattr()、和getattr() 就可以幫助我們達到 A.a -------> B.b 將兩個毫不相幹的對象建立關系映射。甚至隨便建立多級映射,C <------- A -----> B 而不影響映射的函數或者類。
如現在我們寫一個可以完成和用戶交互,實現上傳、下載、查看目錄的類,具體業務邏輯函數就不贅寫了!主要看使用hanattr()和getattr()交互、調用邏輯函數

import socket

class UploadDownload:
    """
        這是一個具有連上遠程服務器,發送命令實現上傳下載功能的類
        _connect() 鏈接遠程服務器
    """

    def __init__(self, IP, PORT):
        self.ip = IP
        self.port = PORT
        self.sock = self._connect()                                                              #調用_connect()函數鏈接遠程服務器
        self.commands = ["upload", "download", "directory"]

    def _connect(self):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((self.ip, self.port))
        return s

    def _command(self):
        while True:
            print("Enter cmd like this : upload /home/user/lina/dance.mp4")     #提示輸入格式
            cmd = input("Enter cmd :").strip()                                                    #輸入指定命令格式,並去除空格
            if not cmd:
                continue
            else:
                cmds = cmd.split(‘‘)                                                                  #簡單處理,將命令和參數分開                  
                if cmds[0] in self.commands:                                                     #如果是可執行命令,就嘗試查找可執行函數
                    try:
                        if hasattr(self,cmds[0]):                                                       # 在類中查找該命令的邏輯函數
                             func = getattr(self, cmds[0])                                               #存在就獲得該函數,並在下一步傳入參數執行
                             func(cmds[1])
                        else:
                             print("請輸入正確的命令格式")
                            continue
                    except Exception as e:
                        print(e)

    def upload(self, dir):
        #這個函數用來上傳
        pass

    def download(self, dir):
        #這個函數用來下載
        pass

    def directory(self, dir):
        #此函數查看文件目錄
        pass

ud = UploadDownload("localhost",5000)
ud._command()

python中的hasattr()、getattr()、setattr()