目錄
1. 概述
本文將根據Github中的一道Python練習題談一談Class中self用法的理解。
2. Github原題
Question 5:
Define a class which has at least two methods:
getString: to get a string from console input
printString: to print the string in upper case.
Also please include simple test function to test the class methods.
中文翻譯如下:
- 定義一個包含至少2個方法的類;
- 方法getString功能要求:自己鍵入一個字符串;
- 方法printString功能要求:以大寫的方式,輸出鍵入的字符串。
- 還要寫出測試自己寫的類和方法的代碼。
3. 類(Class)
本小節內容將根據是什麼(What)、怎麼做(How)談談個人對Class的理解。
3.1 什麼是Class
這裏將用大白話進行闡述。Class就是一個大的集合,用官方用語來說,稱之爲模版。Class這個大的集合中,包含了一些小的集合,稱之爲方法(method)。
3.2 如何創建Class
根據上述這道Github題,可知題目要求我們寫一個Class,這裏將這個Class命名爲StringInOut。命名要求儘可能的簡單,但是又要基本涵蓋這個類的功能。命名規範請參考Python代碼規範要求,這裏不做贅述。
class StringInOut(object):
pass
上面2行代碼即可完成創建一個class的工作。
- 類名爲StringInOut。
- (object)表示繼承的對象,即該類是從哪個類繼承下來的。如果沒有特定對象,所有的類都繼承自object類。
- pass是Python中的一個寫法,表示未完待續的意思,這樣運行就不會報錯。可以先建立,之後再填充功能。
3.3 編寫method函數
沒有實際方法(method)的class只是一個空殼子,不能真正起到Class的作用。給Class命名完成後,開始處理大集合中的小集合method了。method由函數構成。
在本題中,需要構建2個method,名字分別爲getString和printString。getString函數是要實現通過鍵入的方式,獲得一個字符串;printString函數是將鍵入的字符串以大寫的形式打印出來。上述兩個函數的代碼如下:
def getString():
"""
Get a string object by input().
"""
stringIn = input()
return stringIn
def printString(stringIn):
"""
Print the input string in upper case.
"""
print(stringIn.upper())
if __name__ == '__main__':
# 1. Get a string.
print("1. Get a string.")
strIn = getString()
# 2. Print the input string.
print("2. Print the input string.")
printString(strIn)
代碼運行結果如下:
1. Get a string.
hello world!
2. Print the input string.
HELLO WORLD!
輸入“hello world!”,輸出“HELLO WORLD!”。由結果可知函數編寫功能是正確的。但是,只是編寫完成method,未將其放入Class中。下一步工作,就是要將編寫好的method填充進Class中,也是本文的重點。
3.4 類實例化
在上文中,我們提到,類(Class)可以理解爲一個大的集合,或者模版,即爲抽象的東西。
當我們需要引用一個類,如本題中的StringInOut類,需要創建一個實例,代碼如下:
# Create an instance.
str_obj = StringInOut()
所以,類實例化概念:通過建立一個類的實例,簡單理解爲建立引用該類的一個接口,纔可以調用該類內的method方法。
4. __init__()和self
在閱讀Python官方文檔,或者一些源碼中,經常可以看到Class中會包含一個叫做self的參數,以及一個__init__()函數,它們對於類的構建,即將編寫好的函數填充進類中,有什麼幫助,將在這部分詳細敘述。
4.1 def__init__()
init是英文initialize的縮寫,中文即爲初始化的意思。在類中包含一個init()函數,簡單理解爲初始化該類的意思。
當進行類實例化操作時,__init__()方法就會自動調用,進行類自動初始化操作,即一旦建立一個類的實例,它就會自動打開該接口,直接調用類內的方法,不需要做其他初始化工作。
4.2 什麼是self
method與普通的函數只有一個明顯的區別——它們必須有一個額外的第一個參數名稱, 按照慣例它的名稱是 self。
因此,從語法上理解:只要創建一個類,且其包含一些method,該類的初始化方法必須包含self參數,即
def __init__(self):
pass
4.3 self代表類的實例,而非類本身
在本小節中,需要驗證self在類中扮演的是什麼角色。用一段測試代碼進行驗證:
class StringInOut:
def __init__(self):
print(self)
print(self.__class__)
# Create an instance
str_obj = StringInOut()
運行結果:
<__main__.StringInOut object at 0x103fcd390>
<class '__main__.StringInOut'>
從結果可以看出,print(self)輸出的是StringInOut實例的地址,print(self.__class__)則輸出的是StringInOut這個類。
5. 將函數填充進Class中
這一部分將根據題目要求,完成填充工作,完成Class的構建工作。
由上述編寫的兩個函數getString()和printString()可知,getString輸出的值,爲printString輸入的值。在一個類內,要實現你的輸出爲我的輸入,必須通過self進行實現。
在def __init__(self)中定義一個變量,初始值爲空字符串,通過調用getString()方法,進行鍵入賦值,然後調用printString()方法將字符串轉化爲大寫,並輸出。完整代碼如下:
class StringInOut:
def __init__(self):
# Define a variable stringIn.
self.stringIn = ""
def getString(self):
"""
Get a string object by input().
"""
self.stringIn = input()
def printString(self):
"""
Print the input string in upper case.
"""
print(self.stringIn.upper())
if __name__ == '__main__':
# 1. Create an instance
str_obj = StringInOut()
# 2. Get a string.
print("Get a string.")
strIn = str_obj.getString()
# 3. Print the input string.
print("Print the input string.")
str_obj.printString()
代碼運行結果:
Get a string.
hello world
Print the input string.
HELLO WORLD
6. 總結
本文根據Github上的一道簡單的Python練習題,對Class和self進行深入研究和理解,並用代碼進行驗證。在閱讀官方文檔,以及編程過程中,遇到一些晦澀難懂的概念時,必須動手編程,才能比較深刻的理解該定義。
總結:加油,學習編程就要動手幹!