python 的物件設計
在python 中除了可以定義函式外,它也同樣有物件導向的設計,class關鍵字則是用來定義物件的類別,物件類別可以用來產生物件實體 ( instance) ,所以它也可以視為是一種資料型態。class Student(object):
number=''
def __init__(self,number):
self.number=number
def set_number(self,number):
self.number=number
def get_number(self):
return self.number
>>> std=Student('')
>>> print std.get_number()
>>> std=Student('N90000001')
>>> print std.get_number()
N90000001
>>> std.set_number('N00010001')
>>> print std.get_number()
N00010001
>>>
Student物件類別下定義了 " __init__"、" set_number"、"get_number"三個函式,每一個函式的第一個參數都必須是self,是用來代表呼叫此函式的物件實體。
number是此物件的屬性(attribute),
set_number與get_number是此物件的方法(method),
__init__方法是物件的建構子(constructor),是在建立物件實體時系統預設呼叫的函式,
在上述例子中建立std=Student('N90000001')物件std時,就是對應到物件類別下的__init__函式,'N90000001'則是對應到number參數值,set_number與get_number的方法在物件產生時就可以直接使用,類似於java語言的public方法,如 std.set_number('N00010001')、std.get_number()。
類別定義完成後,可以用來產生許多的物件實體,各物件實體間並不會互相影響。
>>> s1=Student('N99010001')
>>> s2=Student('N99020002')
>>> s3=Student('N99030003')
>>> print s1.get_number()
N99010001
>>> print s2.get_number()
N99020002
>>>
另外,在上述的例子中,number屬性也是屬於public的屬性,物件可以直接改變number的值。
>>> s1.number='N99040004'
>>> print s1.get_number()
N99040004
若不想要讓屬性或方法可以直接被拿來使用,我們可以利用兩個底線 " __"作為前置字串,來將它們隱藏起來,類似java語言的protected或private用法。
class Student(object):
__number=''
def __init__(self,number):
self.__number=number
self.__initSomething()
def set_number(self,number):
self.__number=number
def get_number(self):
return self.__number
def __initSomething(self):
print 'init something....'
>>> s1=Student('N99010001')
init something....
>>> s1.__name
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute '__name'
>>> s1.__initSomething()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute '__initSomething'
>>> s1.get_number()
'N99010001'
>>>
但對於了解python語言者而言,其實這種方式只是將這些方法及屬性換個名子而已,若真要呼叫它們,仍然是可以做得到,只是要多一道程序而已,即在方法或屬性的前面加上 " _物件類別名稱" 才能直接存取。所以,只有得知類別名稱的才能直接存取得到,這樣還是可以做到基本的資訊隱藏。
>>> s1._Student__number
'N99010001'
>>> s1._Student__initSomething()
init something....