Python是物件導向程式語言。物件導向程式設計中兩個最基本的概念就是類和物件。類是一羣有着相同屬性和函數的一類物件的模板,類範例化後產生物件。在Python中建立一個類和物件是很容易的。
使用 class 語句來建立一個新類,class 之後爲類的名稱並以冒號結尾,通常類名首字母大寫:
下面 下麪是一個類的例子:
class Document:
"""
這是一個文件字串
"""
# 類變數
WELCOME_STR = 'Welcome! The context for this book is {}.'
# 初始化函數,對建立的物件進行初始化,第一個參數是self,不能有返回值
def __init__(self, title, author, context):
print('init function called')
self.title = title # 成員變數
self.author = author # 成員變數
self.__context = context # 成員變數
# 類函數,常用來實現不同的初始化函數
@classmethod
def create_empty_book(cls, title, author): # 第一參數是cls
print(cls.WELCOME_STR)
return cls(title=title, author=author, context='nothing')
# 成員函數,第一個參數必須是self
def get_context_length(self):
return len(self.__context)
# 靜態函數,通常用在類內其他函數中。
@staticmethod
def get_welcome(context):
return Document.WELCOME_STR.format(context)
可以從下面 下麪幾個方面,認識這個類:
__init__
是初始化函數,當建立了這個類的範例後就會立即呼叫該方法對範例進行初始化。self
表示這個類的一個範例,所有的實體方法的第一個參數必須是self
。__init__
是初始化函數,爲範例物件self
設定了三個範例屬性,分別是title
,author
和__context
。範例屬性與類的具體物件相關,每個物件都有自己的屬性,不會像類變數被所有物件共用。get_context_length
是類的一個成員方法,它的第一個參數必須是self
。可以存取類變數,呼叫成員方法通常是通過範例化的物件,當然是用類名呼叫也是可以的,不過要傳遞一個物件物件進去。create_empty_book
是類的一個類方法,用@classmethod標識,它的第一個參數必須是cls
。類方法可以存取類變數,通常通過類名呼叫。get_welcome
是類的靜態方法,它被設計用來在類內部其他函數中使用,不過在類外部也可以通過類名和範例物件呼叫。範例化類在其他程式語言中一般用關鍵字 new,比如Java語言。但是在 Python 中並沒有這個關鍵字,類的範例化類似呼叫函數一樣,類名加上括號,括號裏面是類的屬性值。
以下使用類的名稱 Document 來範例化,並通過 __init__
方法接收屬性。
d=Document("demo", "chunming", "show you class")
上面一條語句其實Python是執行兩步:
__new__
方法建立範例物件。上面類並沒有__new__
方法呀。一般不用自己定義,Python預設呼叫該類的直接父類別的__new__
方法來構造該類的範例,如果該類的父類別也沒__new__
方法, 那麼將一直按此規矩追溯至object的__new__
方法。Document類的直接父類別是object,所以Document類範例化時,是呼叫的object類的__new__
方法。看下object的__new__
方法是如何定義的:
@staticmethod # known case of __new__
def __new__(cls, *more): # known special case of object.__new__
""" Create and return a new object. See help(type) for accurate signature. """
pass
可見object的__new__
方法,是一個靜態方法,通常使用方式是object.__new__。
__init__
方法對物件進行初始化。如果沒定義,則不會進行特別的初始化動作。範例化類之後,就可以用物件存取類變數、範例屬性、類方法、實體方法和靜態方法了。
在上面的類程式碼檔案中,寫下如下測試程式碼:
if __name__ == '__main__':
d = Document("demo", "chunming", "show you class")
print("存取類變數=", d.WELCOME_STR) # 1.範例物件存取類變數
d0 = d.create_empty_book("有預設content", "範例物件") # 2.範例物件呼叫類方法
print(d.get_welcome("範例物件呼叫靜態函數")) # 3. 範例物件呼叫靜態方法
print(d.get_context_length()) # 4. 範例物件呼叫成員方法
print(Document.WELCOME_STR) # 5. 類名存取類變數
# print(Document.title) # 不可以。
print(Document.get_context_length(d)) # 6. 類名存取成員方法
f = Document.create_empty_book("static", "liu") # 7. 類名存取類方法
print(Document.get_welcome("aa")) # 8. 類名存取靜態方法
可以存取類的屬性和方法,都是通過點號方式。 範例物件和類都可以存取類變數、類方法、實體方法和靜態方法。但是類不能存取範例屬性。
有兩種辦法可以檢視類有哪些屬性。
['WELCOME_STR', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'create_empty_book', 'get_context_length', 'get_welcome']
__dict__
,是一個字典,包含屬性的名字和值{'__module__': '__main__', '__doc__': '\n 這是一個文件字串\n ', 'WELCOME_STR': 'Welcome! The context for this book is {}.', '__init__': <function Document.__init__ at 0x1101f9f80>, 'create_empty_book': <classmethod object at 0x110260750>, 'get_context_length': <function Document.get_context_length at 0x11025d710>, 'get_welcome': <staticmethod object at 0x110260790>, '__dict__': <attribute '__dict__' of 'Document' objects>, '__weakref__': <attribute '__weakref__' of 'Document' objects>}
從dir函數和__dict__
的輸出可以看出,有些屬性我們在Document類中並沒有定義,比如__module__
、__class__
、__dict__
以及__doc__
等,這些屬性是Python爲每一個類自動設定的。
C.__name__
,表示類C的名字C.__dict__
,表示類C的屬性以及值。C.__module__
,表示類C的定義所在的模組名稱,獨立執行模組時爲字串__main__
。模組被匯入時,被設定爲模組的名稱。i.__class__
,表示範例i所屬的類C.__bases__
,表示類C的所有直接父類別組成的元組,不包括父類別的父類別C.__doc__
,表示類C的文件字串。__init__
表示建構函式,對生成的物件進行初始化操作,一個物件生成後會被自動呼叫的函數。@staticmethod
表示@classmethod
來宣告。__init__
建構函式,比如上文程式碼中,我們使用 create_empty_book 類函數,來創造新的書籍物件,用它來創造的書籍其 context 一定爲 ‘nothing’。好了。Python類與物件入門就介紹到這裏。下一小節我們繼續對屬性進行輸入介紹。