Python進階之物件導向(類的特殊方法)

Stefan的程式碼小屋發表於2018-04-23

1. 與類有關的幾個函式

hasattr()       #判斷物件object是否包含名為name的特性
getattr()		# 得到物件的某個屬性值 (獲取器)
setattr()		# 給物件新增某個屬性值 (設定器 ),(例項呼叫,只對當前例項有用),類呼叫,對所有例項有用
delattr()		# 刪除物件屬性 (刪除器)
isinstance()  	# 檢查物件是否是類的物件,返回True或False
issubclass()  	# 檢查一個類是否是另一個類的子類。返回True或False
複製程式碼

程式碼示例:

class A():
    name=1
    def test(self):
        raise IOError("錯誤")
print(hasattr(A,"nam")) #False
print(getattr(A,"name")) #1
setattr(A,"name","xfy")
print(getattr(A,"name")) #xfy
delattr(A,"name")
setattr(A,"name","xfy")
print(getattr(A,"name"))#xfy
print(hasattr(A,"test"))#True
print(getattr(A,"test")) #<function A.test at 0x000001D270FDBC80>
a=A()
print(isinstance(a,A)) #True
複製程式碼

注:

  • setattr:例項呼叫,只對當前例項有用,類呼叫,對所有例項有用。
  • delattr方法只能傳類,不能傳例項
  • hasattr傳入類就是檢視該類是否有某屬性,傳例項是檢視例項對應的該類是否有某屬性。(所以就是無論怎樣都是檢視類),在python類的定義中方法也是一種特殊的屬性。

再看示例:

a.name=12  # 並不會修改類的name
print(a.name) #12
print(A.name)#1
複製程式碼

例項修改類變數只是改了自己當前範圍的值,並不能改變累的屬性。

2. 類的特殊方法

#類屬性:
    __dict__ 	# 類的屬性(包含一個字典,由類的資料屬性組成)
    __doc__ 	# 類的文件字串
#類方法:  
    __init__    # 初始化
    __repr__    # 直接返回這個物件  repr() 函式就是呼叫物件的這個方法
    __str__     # print(obj) 如果類裡面定義了__repr__,沒有定義__str__   print(obj)也會返回__repr__的內容,或者說__repr__的優先順序更高
    __call__    # Obj() 使例項可被呼叫
    
#運算子方法
    __add__(self,other)     #x+y
    __sub__(self,other)     #x-y 
    __mul__(self,other)     #x*y  
    __mod__(self,other)     #x%y
    __iadd__(self,other)    #x+=y
    __isub__(self,other)    #x-=y 
    __radd__(self,other)    #y+x
    __rsub__(self,other)    #y-x 
    __imul__(self,other)    #x*=y 
    __imod__(self,other)    #x%=y  不v
複製程式碼

示例:

class B():
    '''
    這是一個測試用的類
    '''
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __str__(self):
        return "這是一個B類"
    def __call__(self, *args, **kwargs):
        return self.name

b=B("xfy",20)
print(B.__doc__)#這是一個測試用的類
print(b.__dict__)#{'name': 'xfy', 'age': 20}
print(b)#這是一個B類
print(b.__repr__())#<__main__.B object at 0x000001AC26405F28>
print(b.__str__())#這是一個B類
print(b())#xfy
複製程式碼

注: __repr__和__str__的區別

__repr__是給程式設計師和機器看的。

__str__可重寫給使用者看了。

實現兩個例項像數字一樣相加

示例:

#為什麼1+2,但是b+c不行
#我們來看dir(1)
print(dir(1))#['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']
#1有一個__add__介面,如果我們也能在B裡實現這個__add__,不也能跟隨我們的意願做數學操作了嗎?
class B():
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __add__(self, other):
        return self.age+other.age
b=B("xfy",20)
c=B("stefan",21)
print(b+c)#41,b+c是兩個人年齡的和
複製程式碼

所以只要我們在類里加了相應的介面就能一些特殊的功能。

相關文章