class Employee:
def setname(self, who):
self.name = who
def display(self):
print self.name
self相當於C++中的this指針。C++的this指針是隱含的,但Python中self是需要顯示地寫出。
2. Python 把對象(object)分爲class object和instance object。每個類型都有一個對象,該對象能生成多個實例對象。
3. 可以通過類型對象或者實例對象調用類型的方法。比如下列兩種調用setname的方式是等價的:
e = Employee()
e.setname('Harry')
Employee.setname(e, 'Harry')
4. 實例對象的成員變量不需要提前聲明,它們在賦值時自動創建。
5. 可以在類型定義之外爲實例對象添加新的成員變量,比如:
e.lastname = 'He'
6. 可以在類型定義之外爲類型添加新的成員函數,比如:
def upperName(self):
return self.name.upper()
Employee.method = upperName
e.method()
7. 如果子類沒有重寫__init__,會自動調用父類的__init__函數:
class A:
def __init__(self):
print 'A is instantiated'
class B (A):
pass
if __name__ == '__main__':
b = B()
此時A.__init__仍然會被調用
如果子類重寫了__init__函數,父類的__init__函數不會自動自動被調用,如以下代碼:
class A:
def __init__(self):
print 'A is instantiated'
class B (A):
def __init__(self):
print 'B is instantiated'
if __name__ == '__main__':
b = B()
如果希望父類的__init__函數被調用,需要在子類的__init__函數裏顯示地調用:如以下代碼:
class A:
def __init__(self):
print 'A is instantiated'
class B (A):
def __init__(self):
A.__init__(self)
print 'B is instantiated'
if __name__ == '__main__':
b = B()
8. Python的class不支持類似於C++/C#/Java的static函數/方法
9. metaclass可以用來生成新的class。詳細討論可以參考http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python。
10. static變量和實例的變量:
>>> class Test(object):
... i = 3
...
>>> Test.i
3
>>> t = Test()
>>> t.i # static variable accessed via instance
3
>>> t.i = 5 # but if we assign to the instance ...
>>> Test.i # we have not changed the static variable
3
>>> t.i # we have overwritten Test.i on t by creating a new attribute t.i
5
>>> Test.i = 6 # to change the static variable we do it by assigning to the class
>>> t.i
5
>>> Test.i
6
11.在Python中沒有類似於C/C++/C#的enum類型。下面是幾種用Python模擬enum的方法:
(1) 生成新的type:
def enum(**enums):
return type('Enum', (), enums)
>>> Numbers = enum(ONE=1, TWO=2, THREE='three')
>>> Numbers.ONE
1
>>> Numbers.TWO
2
>>> Numbers.THREE
'three'
或者自動編號:
def enum(*sequential, **named):
enums = dict(zip(sequential, range(len(sequential))), **named)
return type('Enum', (), enums)
>>> Numbers = enum('ZERO', 'ONE', 'TWO')
>>> Numbers.ZERO
0
>>> Numbers.ONE
1
如果需要逆向查找:
def enum(*sequential, **named):
enums = dict(zip(sequential, range(len(sequential))), **named)
reverse = dict((value, key) for key, value in enums.iteritems())
enums['reverse_mapping'] = reverse
return type('Enum', (), enums)
>>> Numbers.reverse_mapping['three']
'THREE'
(2)基於set:
class Enum(set):
def __getattr__(self, name):
if name in self:
return name
raise AttributeError
Animals = Enum(["DOG", "CAT", "HORSE"])
print Animals.DOG
(3)基於tuple:
(Pen, Pencil, Eraser) = range(0, 3)
或者:
class Stationery:
(Pen, Pencil, Eraser) = range(0, 3)
12. 如果類型需要支持+、-、×、/,則需要添加__add__、__sub__、__mul__、__rmul__、__div__等。如果需要支持比較,則需要添加__cmp__。完整列表參考Think like a Computer Scientist的Appendix B。