python 的物件設計

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....