魔術方法
基本定製
說明
C.__init__(self[, arg1, ...]) 構造器(帶一些可選的參數) C.__new__(self[, arg1, ...]) 構造器(帶一些可選的參數);通常用在設置不變數據類型的子類 C.__del__(self) 解構器 C.__str__(self) 可打印的字符輸出;內建str()及print 語句 C.__repr__(self) 運行時的字符串輸出;內建repr() ‘‘ 和 操作符 C.__unicode__(self)b Unicode 字符串輸出;內建unicode() C.__call__(self, *args) 表示可調用的實例 C.__nonzero__(self) 爲object 定義False 值;內建bool() (從2.2 版開始) C.__len__(self) “ ” 長度(可用於類);內建len()
示例
class A(): def __init__(self): print "call __init__" self.a = 1 def __new__(self): print "call __new__" def __del__(self): print "call __del__" def __str__(self): print "call __str__" return "class A str" def __repr__(self): print "call __repr__" return "class A repr" def __unicode__(self): print "call __unicode__" return "class A unicode" def __nozero__(self): print "call __nozero__" return 1 def __len__(self): print "call __len__" return 1 #定以後callable(instance) True def __call__(self, *args): print "call __call__" a = A() print a repr(a) unicode(a) print bool(a) print len(a) print callable(a)
A.new和init區別
class A(object): def __init__(self): print "call __init__" self.value = 1 def __new__(cls): print "call __new__" return super(A, cls).__new__(cls) a = A() print a.value
__new__:創建對象時調用,返回當前對象的一個實例,相當於java裏面的構造器 一般是用於繼承內置類的,返回值是一個對象
使用:需要控制一個新實例的創建,一般情況下不會使用,除非需要子類化不可變類型例如str/int/unicode/tuple
__init__:創建完對象後調用,對當前對象的實例的一些初始化,無返回值
使用:需要控制一個實例的初始化
可以這樣理解,默認是創建(new),然後調用__init__ (new的時候,self還不存在, init的時候self已經存在了)
對象值比較
說明
C.__cmp__(self, obj) 對象比較;內建cmp() C.__lt__(self, obj) and 小於/小於或等於;對應<及<=操作符 C.__le__(self,obj) C.__gt__(self, obj) and 大於/大於或等於;對應>及>=操作符 C.__ge__(self,obj) C.__eq__(self, obj) and 等於/不等於;對應==,!=及<>操作符 C.__ne__(self,obj)
示例
class A(): def __init__(self, value): self.value = value def __cmp__(self, obj): print "call __cmp__" return self.value - obj.value def __lt__(self, obj): print "call __lt__" return self.value < obj.value def __gt__(self, obj): print "call __gt__" return self.value > obj.value def __eq__(self, obj): print "call __eq__" return self.value == obj.value a1 = A(1) a2 = A(2) print cmp(a1,a2) print a1 < a2 print a1 > a2 print a1 == a2
屬性操作
說明:
C.__getattr__(self, attr) 獲取屬性;內建getattr();僅當屬性沒有找到時調用 C.__setattr__(self, attr, val) 設置屬性 C.__delattr__(self, attr) 刪除屬性 C.__getattribute__(self, attr) 獲取屬性;內建getattr();總是被調用 C.__get__(self, attr) (描述符)獲取屬性 C.__set__(self, attr, val) (描述符)設置屬性 C.__delete__(self, attr) (描述符)刪除屬性
示例
class A(): def __init__(self): self.value = 1 def __getattr__(self, name): print "call __getattr__" try: return self.__dict__[name] except: return "not found" def __setattr__(self, name, value): print "call __setattr__" self.__dict__[name] = value def __delattr__(self, name): print "call __delattr__" del self.__dict__[name] def __getattribute__(self, name): print "call __getattribute__" return self.__dict__[name] def __get__(self, name): pass def __set__(self, name, value): pass def __del__(self): pass a = A() print getattr(a, "value") print getattr(a, "name") del a.value
A.get/getattr/getattribute區別
object.getattr(self, name)
當一般位置找不到attribute的時候,會調用getattr,返回一個值或AttributeError異常。
object.getattribute(self, name)
無條件被調用,通過實例訪問屬性。如果class中定義了__getattr__(),則__getattr__()不會被調用(除非顯示調用或引發AttributeError異常)
object.get(self, instance, owner)
如果class定義了它,則這個class就可以稱爲descriptor。owner是所有者的類,instance是訪問descriptor的實例,如果不是通過實例訪問,而是通過類訪問的話,instance則爲None。(descriptor的實例自己訪問自己是不會觸發__get__,而會觸發__call__,只有descriptor作爲其它類的屬性纔有意義。)
數值及二進制
二元
C.__*add__(self, obj) 加;+操作符 C.__*sub__(self, obj) 減;-操作符 C.__*mul__(self, obj) 乘;*操作符 C.__*div__(self, obj) 除;/操作符 C.__*truediv__(self, obj) True 除;/操作符 C.__*floordiv__(self, obj) Floor 除;//操作符 C.__*mod__(self, obj) 取模/取餘;%操作符 C.__*divmod__(self, obj) 除和取模;內建divmod() C.__*pow__(self, obj[, mod]) 乘冪;內建pow();**操作符 C.__*lshift__(self, obj) 左移位;<<操作符
二進制
C.__*rshift__(self, obj) 右移;>>操作符 C.__*and__(self, obj) 按位與;&操作符 C.__*or__(self, obj) 按位或;|操作符 C.__*xor__(self, obj) 按位與或;^操作符
一元
C.__neg__(self) 一元負 C.__pos__(self) 一元正 C.__abs__(self) 絕對值;內建abs() C.__invert__(self) 按位求反;~操作符
數值轉換
C.__complex__(self, com) 轉爲complex(複數);內建complex() C.__int__(self) 轉爲int;內建int() C.__long__(self) 轉爲long;內建long() C.__float__(self) 轉爲float;內建float()
其他
C.__oct__(self) 八進制表示;內建oct() C.__hex__(self) 十六進制表示;內建hex() C.__coerce__(self, num) 壓縮成同樣的數值類型;內建coerce() C.__index__(self)g 在有必要時,壓縮可選的數值類型爲整型(比如:用於切片索引等等
序列
說明
C.__len__(self) 序列中項的數目 C.__getitem__(self, ind) 得到單個序列元素 C.__setitem__(self, ind,val) 設置單個序列元素 C.__delitem__(self, ind) 刪除單個序列元素 C.__getslice__(self, ind1,ind2) 得到序列片斷 C.__setslice__(self, i1, i2,val) 設置序列片斷 C.__delslice__(self, ind1,ind2) 刪除序列片斷 C.__contains__(self, val) f 測試序列成員;內建in 關鍵字 C.__*add__(self,obj) 串連;+操作符 C.__*mul__(self,obj) 重複;*操作符 C.__iter__(self) 創建迭代類;內建iter()
示例
class A(): def __init__(self): print "call __init__" self.value = [1,2,3,4,5,6] def __len__(self): print "call __len__" return len(self.value) def __getitem__(self, index): print "call __getitem__" return self.value[index] def __setitem__(self, index, value): print "call __setitem__" self.value[index] = value def __delitem__(self, index): print "call __delitem__" del self.value[index] a = A() print len(a) print a[2] a[2] = 99 del a[2]
映射
C.__len__(self) mapping 中的項的數目 C.__hash__(self) 散列(hash)函數值 C.__getitem__(self,key) 得到給定鍵(key)的值 C.__setitem__(self,key,val) 設置給定鍵(key)的值 C.__delitem__(self,key) 刪除給定鍵(key)的值 C.__missing__(self,key) 給定鍵如果不存在字典中,則提供一個默認值
內置類變量
這期的話題有點簡單, 整理下常見的模塊內置方法
剛開始學Python的時候, 看到if __name__ == '__main__': main()
就不明覺厲了, 一直好奇__name__
這貨到底是個什麼東東
實際上, __name__
是Python中模塊的內置屬性, 除此之外, 經常用到的還有__file__
, __doc__
, __all__
, __package__
等等
__name__
__name__
是模塊內置的一個屬性, 一般如果模塊是被引用的時候, 它的值是模塊名, 如果這個python文件被直接運行, 那麼它的值是'__main__'
>>> __name__
'__main__'
>>> import os
>>> os.__name__
'os'
所以我們寫一個腳本的時候,通過判斷__name__
來確定腳本是被引用, 還是被直接運行
if __name__ == `__main__`:
main()
__file__
被引用模塊文件的路徑
>>> import os
>>> os.__file__
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'
__doc__
模塊的註釋文檔
class MyClass:
"""這是MyClass的註釋,
調用下面myClass.__doc__的時候會返回這段內容"""
def funcA(self):
"""這是funcA的註釋文檔"""
return "hello"
myClass = MyClass()
調用myClass.__doc__
會返回MyClass
的註釋文檔, myClass.funcA.__doc__
會返回funcA
的註釋文檔
如果執行help(MyClass)
, 所看到的文檔實際就是DocStrings
收集該類下所有的註釋生成的文檔
__all__
當你寫一個Python的模塊的時候, 一般在__init__.py
中指定__all__
來表示當這個模塊被import * from xxx
的時候, 有哪些模塊會被import
進來,
當然, 我們推薦儘量不使用import *
__package__
__package__
主要是爲了相對引用而設置的一個屬性, 如果所在的文件是一個package
的話, 它和__name__
的值是一樣的, 如果是子模塊的話, 它的值就跟父模塊一致
比如 modA/modB/aa.py
中__name__
的值是modA.modB.aa
__package__
是modA.modB
modA/modB/__init__.py
中__name__
和__package__
的值都是modA.modB
如何查看內建方法和變量的文檔
>>>print dir(an_object_name)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__getitem__', '__getslice__', '__hash__', '__init__', '__new__', '__reduc
e__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__',
'__str__', '__subclasshook__', '__unicode__', 'args', 'message']
然後使用help(***)來查詢文檔信息