1. 程式人生 > 實用技巧 >1210python基礎2

1210python基礎2

1.資料結構Python中有三種內建的資料結構——列表、元組和字典(30).列表list是處理一組有序的資料結構,即你可以在一個列表中儲存一個 序列 的資料。並且裡面的值是能夠被改變的列表中的專案應該包括在方括號中,這樣Python就知道你是在指明一個列表。一旦你建立了一個列表,你可以新增、刪除或是搜尋列表中的專案。[1,2,3,4] 逗號分割由於你可以增加或刪除專案,我們說列表是 可變的 資料型別,即這種型別是可以被改變的。
程式碼示例shoplist = ['apple', 'mango', 'carrot', 'banana']print 'I have', len(shoplist),'items to purchase.'print 'These items are:', # Notice the comma at end of the linefor item in shoplist:
print item,
print '\nI also have to buy rice.'shoplist.append('rice')print 'My shopping list is now', shoplist
print 'I will sort my list now'shoplist.sort()print 'Sorted shopping list is', shoplist
print 'The first item I will buy is', shoplist[0]olditem = shoplist[0]del shoplist[0]print 'I bought the', olditemprint 'My shopping list is now', shoplist
print語句的結尾使用了一個 逗號 來消除每個print語句自動列印的換行符
sort方法來對列表排序。需要理解的是,這個方法影響列表本身,而不是返回一個修改後的列表del語句為我們從列表中刪除它。我們指明我們想要刪除列表中的第一個元素,因此使用del shoplist[0]可以通過help(list)獲得關於list完整的資訊(31).元組
元組和列表十分類似,只不過元組和字串一樣是 不可變的 即你不能修改元組。元組通過括號中用逗號分割的專案定義。元組通常用在使語句或使用者定義的函式能夠安全地採用一組值的時候,即被使用的元組的值不會改變。程式碼示例zoo = ('wolf', 'elephant', 'penguin')print 'Number of animals in the zoo is', len(zoo)new_zoo = ('monkey', 'dolphin', zoo)print 'Number of animals in the new zoo is', len(new_zoo)print 'All animals in new zoo are', new_zooprint 'Animals brought from old zoo are', new_zoo[2]print 'Last animal brought from old zoo is', new_zoo[2][2]
元組是不能改變的zoo.__add__('tiger')元組結合列印語句
age = 22name = 'Swaroop'print '%s is %d years old' % (name, age)print 'Why is %s playing with that python?' % name
%s表示字串或%d表示整數。元組必須按照相同的順序來對應
(32).字典與集合
字典類似於java的map使用不可變的物件(比如字串)來作為字典的鍵,但是你可以把不可變或可變的物件作為字典的值。基本說來就是,你應該只使用簡單的物件作為鍵。鍵值對在字典中以這樣的方式標記:d = {key1 : value1, key2 : value2 }。注意它們的鍵/值對用冒號分割,而每組KV使用逗號分割,所有這些都包括在花括號中。記住字典中的鍵/值對是沒有順序的。如果你想要一個特定的順序,那麼你應該在使用前自己對它們排序。字典是dict類的例項/物件。
程式碼示例ab = { 'Swaroop' : '[email protected]','Larry' : '[email protected]','Matsumoto' : '[email protected]','Spammer' : '[email protected]'}
print "Swaroop's address is %s" % ab['Swaroop']# Adding a key/value pairab['Guido'] = '[email protected]'# Deleting a key/value pairdel ab['Spammer']print '\nThere are %d contacts in the address-book\n' % len(ab)#迴圈for name, address in ab.items(): print 'Contact %s at %s' % (name, address)#判斷是否存在if 'Guido' in ab: # OR ab.has_key('Guido') print "\nGuido's address is %s" % ab['Guido']修改或者新增
list = {1:'a',2:'b'}
list[3]=('c')
list[3]=('d')

del語句來刪除鍵/值對。我們只需要指明字典和用索引操作符指明要刪除的鍵,然後把它們傳遞給del語句使用字典的items方法,來使用字典中的每個鍵/值對。這會返回一個元組的列表,其中每個元組都包含一對專案——鍵與對應的值,然後分別賦給for..in迴圈中的變數name和address使用in操作符來檢驗一個鍵/值對是否存在,或者使用dict類的has_key方法集合
setset和dict類似,也是一組key的集合,但不儲存value。由於key不能重複,所以,在set中,沒有重複的key。
要建立一個set,需要提供一個list作為輸入集合:s = set([1, 2, 3])注意,傳入的引數[1, 2, 3]是一個list,而顯示的{1, 2, 3}只是告訴你這個set內部有1,2,3這3個元素,顯示的順序也不表示set是有序的。。重複元素在set中自動被過濾:s = set([1, 1, 2, 2, 3, 3])通過add(key)方法可以新增元素到set中,可以重複新增,但不會有效果:
s.add(4){1, 2, 3, 4}s.add(4)通過remove(key)方法可以刪除元素:
s.remove(4)set可以看成數學意義上的無序和無重複元素的集合,因此,兩個set可以做數學意義上的交集、並集等操作:
s1 = set([1, 2, 3])s2 = set([2, 3, 4])s1 & s2{2, 3}s1 | s2{1, 2, 3, 4}set和dict的唯一區別僅在於沒有儲存對應的value,但是,set的原理和dict一樣,所以,同樣不可以放入可變物件,因為無法判斷兩個可變物件是否相等,也就無法保證set內部“不會有重複元素”。放可變的物件沒有報錯,因為可變的物件不會改變
(33).列表、元組和字串都可以看成一序列資料,都可以通過索引操作符讓我們可以從序列中抓取一個特定專案或取其中一部分資料,也就是序列資料的切片
程式碼示例shoplist = ['apple', 'mango', 'carrot', 'banana']# Indexing or 'Subscription' operationprint 'Item 0 is', shoplist[0]print 'Item 1 is', shoplist[1]print 'Item 2 is', shoplist[2]print 'Item 3 is', shoplist[3]print 'Item -1 is', shoplist[-1]print 'Item -2 is', shoplist[-2]# Slicing on a listprint 'Item 1 to 3 is', shoplist[1:3]print 'Item 2 to end is', shoplist[2:]print 'Item 1 to -1 is', shoplist[1:-1]print 'Item start to end is', shoplist[:]# Slicing on a stringname = 'swaroop'print 'characters 1 to 3 is', name[1:3]print 'characters 2 to end is', name[2:]print 'characters 1 to -1 is', name[1:-1]print 'characters start to end is', name[:][0:-1] 左閉右開索引同樣可以是負數,在那樣的情況下,位置是從序列尾開始計算的切片操作符是序列名後跟一個方括號,方括號中有一對可選的數字,並用冒號分割,數是可選的,而冒號是必須的。切片操作符中的第一個數(冒號之前)表示切片開始的位置,第二個數(冒號之後)表示切片到哪裡結束。如果不指定第一個數,Python就從序列首開始。如果沒有指定第二個數,則Python會停止在序列尾。注意,返回的序列從開始位置 開始 ,剛好在 結束 位置之前結束。即開始位置是包含在序列切片中的,而結束位置被排斥在切片外。(34).引用
當你建立一個物件並給它賦一個變數的時候,這個變數僅僅 引用 那個物件,而不是表示這個物件本身!也就是說,變數名指向你計算機中儲存那個物件的記憶體。這被稱作名稱到物件的繫結。程式碼示例print 'Simple Assignment'shoplist = ['apple', 'mango', 'carrot', 'banana']mylist = shoplist # mylist is just another name pointing to the same object!del shoplist[0]print 'shoplist is', shoplistprint 'mylist is', mylist
del mylist[0]
print 'shoplist is', shoplist
print 'mylist is', mylist
刪除mylist[0]也會改變shoplistprint 'Copy by making a full slice'mylist = shoplist[:]del mylist[0] # remove first itemprint 'shoplist is', shoplistprint 'mylist is', mylist
(35).物件的深拷貝與淺拷貝
程式碼示例import copya = [1, 2, 3, 4, ['a', 'b']] #原始物件
b = a #賦值,傳物件的引用c = copy.copy(a) #物件拷貝,淺拷貝d = copy.deepcopy(a) #物件拷貝,深拷貝
a.append(5) #修改物件aa[4].append('c') #修改物件a中的['a', 'b']陣列物件
print 'a = ', aprint 'b = ', bprint 'c = ', cprint 'd = ', d
(36).其它常用字串的操作程式碼示例name = 'Swaroop' # This is a string objectif name.startswith('Swa'): print 'Yes, the string starts with "Swa" 'if 'a' in name: print 'Yes, it contains the string "a" 'if name.find('war') != -1: print 'Yes, it contains the string "war" 'delimiter = '_*_'mylist = ['Brazil', 'Russia', 'India', 'China']print delimiter.join(mylist)2.物件
(37).self等於java的this當你呼叫這個物件的方法MyObject.method()的時候,這會由Python自動轉為MyClass.method(MyObject),所以如果你有一個不需要引數的方法,你還是得給這個方法定義一個self引數。
建立一個類程式碼示例class Person: pass # An empty block
p = Person()
有方法的物件程式碼示例class Person: def sayHi(self): print 'Hello, how are you?'
p = Person()p.sayHi()
(38).__init__方法__init__方法在類的一個物件被建立時,馬上執行這個方法可以用來對你的物件做一些你希望的 初始化 。注意,這個名稱的開始和結尾都是雙下劃線。類似於java的建構函式
程式碼示例class Person: def __init__(self, name): self.name = name #d定義了name並且賦值
def sayHi(self): print 'Hello, my name is', self.name
p = Person('Swaroop')p.sayHi()print p(39).類變數與物件的變數
有兩種型別的 域 ——類的變數和物件的變數,它們根據是類還是物件 擁有 這個變數而區分。類的變數 由一個類的所有物件(例項)共享使用。只有一個類變數的拷貝,所以當某個物件對類的變數做了改動的時候,這個改動會反映到所有其他的例項上。
物件的變數 由類的每個物件/例項擁有。因此每個物件有自己對這個域的一份拷貝,即它們不是共享的,在同一個類的不同例項中,雖然物件的變數有相同的名稱,但是是互不相關的。程式碼示例class Person: '''Represents a person.''' population = 0 def __init__(self, name): '''Initializes the person's data.''' self.name = name print '(Initializing %s)' % self.name # When this person is created, he/she # adds to the population Person.population += 1 def __del__(self): '''I am dying.''' print '%s says bye.' % self.name Person.population -= 1 if Person.population == 0: print 'I am the last one.' else: print 'There are still %d people left.' % Person.population
def sayHi(self): '''Greeting by the person. Really, that's all it does.''' print 'Hi, my name is %s.' % self.name
def howMany(self): '''Prints the current population.''' if Person.population == 1: print 'I am the only person here.' else: print 'We have %d persons here.' % Person.population
swaroop = Person('Swaroop')swaroop.sayHi()swaroop.howMany()kalam = Person('Abdul Kalam')kalam.sayHi()kalam.howMany()swaroop.sayHi()swaroop.howMany()print
這裡,population屬於Person類,因此是一個類的變數。name變數屬於物件(它使用self賦值)因此是物件的變數。可以用類名或物件名或self來訪問類變數,但是物件的變數和方法通常用物件名或self來訪問我們還看到docstring對於類和方法同樣有用。我們可以在執行時使用Person.__doc__和Person.sayHi.__doc__來分別訪問類與方法的文件字串。如同__init__方法一樣方法__del__,它在物件消逝的時候被呼叫。但是很難保證這個方法究竟在 什麼時候 執行。如果你想要指明它的執行,你就得使用del語句。Python中所有的類成員(包括資料成員)都是公共的,如果你使用的資料成員名稱以 雙下劃線字首 比如__privatevar,Python的名稱管理體系會有效地把它作為私有變數。
方法私有類屬性私有
__population = 0
通用命名規範
如果某個變數只想在類或物件中使用,就應該以單下劃線字首。而其他的名稱都將作為公共的,可以被其他類/物件使用。記住這只是一個慣例,並不是Python所要求的(與雙下劃線字首不同)。import * 就不會匯入它(40).繼承與java中的繼承概念一樣,同樣能用子類為父類建立例項,但有一些不同
程式碼示例class SchoolMember: '''Represents any school member.''' def __init__(self, name, age): self.name = name self.age = age print '(Initialized SchoolMember: %s)' % self.name
def tell(self): '''Tell my details.''' print 'Name:"%s" Age:"%s"' % (self.name, self.age),
class Teacher(SchoolMember): '''Represents a teacher.''' def __init__(self, name, age, salary): SchoolMember.__init__(self, name, age) self.salary = salary print '(Initialized Teacher: %s)' % self.name def tell(self): SchoolMember.tell(self) print 'Salary: "%d"' % self.salary
class Student(SchoolMember): '''Represents a student.''' def __init__(self, name, age, marks): SchoolMember.__init__(self, name, age) #super(self.__class__, self).__init__(name,age) 使用這種方法父類得繼承object
self.marks = marks print '(Initialized Student: %s)' % self.name
def tell(self): SchoolMember.tell(self) print 'Marks: "%d"' % self.marks
t = Teacher('Mrs. Shrividya', 40, 30000)s = Student('Swaroop', 22, 75)print # prints a blank linemembers = [t, s]for member in members: member.tell() # works for both Teachers and Students為了使用繼承,我們把基本類的名稱作為一個元組跟在定義類時的類名稱之後。然後,基本類的__init__方法把子類的self變數傳遞過去,這樣我們就可以初始化物件的基本類部分。這一點十分重要——Python不會自動呼叫基本類的constructor,你得親自專門呼叫它。

我們還觀察到我們在方法呼叫之前加上類名稱字首,然後把self變數及其他引數傳遞給它。注意,在我們使用SchoolMember類的tell方法的時候,我們把Teacher和Student的例項僅僅作為SchoolMember的例項。
另外,在這個例子中,我們呼叫了子型別的tell方法,而不是SchoolMember類的tell方法。可以這樣來理解,Python總是首先查詢對應型別的方法。如果它不能在子類中找到對應的方法,它才開始到基本類中逐個查詢
基本類是在類定義的時候,在元組之中指明的。如果在繼承元組中列了一個以上的類,那麼它就被稱作 多重繼承 。
3.輸入/輸出(41).檔案通過建立一個file類的物件來開啟一個檔案,分別使用file類的read、readline或write方法來恰當地讀寫檔案。對檔案的讀寫能力依賴於你在開啟檔案時指定的模式。最後,當你完成對檔案的操作的時候,你呼叫close方法來告訴Python我們完成了對檔案的使用。程式碼示例poem = '''\Programming is funWhen the work is doneif you wanna make your work also fun:use Python!'''f = file('poem.txt', 'w') # open for 'w'riting寫f.write(poem) # write text to filef.close() # close the filef = file('poem.txt')# if no mode is specified, 'r'ead mode is assumed by defaultwhile True: line = f.readline() if len(line) == 0: # Zero length indicates EOF break print line, # Notice comma to avoid automatic newline added by Pythonf.close() # close the filejava的自動關閉是怎麼回事?????with open方式:https://www.cnblogs.com/ymjyqsx/p/6554817.html
with open('/path/to/file', 'r') as f:
    print(f.read())

通過指明我們希望開啟的檔案和模式來建立一個file類的例項。
1)、r 開啟只讀檔案,該檔案必須存在。2)、r+ 開啟可讀寫的檔案,該檔案必須存在。3)、w 開啟只寫檔案,若檔案存在則檔案長度清為0,即該檔案內容會消失。若檔案不存在則建立該檔案。4)、w+ 開啟可讀寫檔案,若檔案存在則檔案長度清為0,即該檔案內容會消失。若檔案不存在則建立該檔案。5)、a 以附加的方式開啟只寫檔案。若檔案不存在,則會建立該檔案,如果檔案存在,寫入的資料會被加到檔案尾,即檔案原先的內容會被保留。6)、a+ 以附加方式開啟可讀寫的檔案。若檔案不存在,則會建立該檔案,如果檔案存在,寫入的資料會被加到檔案尾後,即檔案原先的內容會被保留。7)、上述的形態字串都可以再加一個b字元,如rb、w+b或ab+等組合,加入b 字元用來告訴函式庫開啟的檔案為二進位制檔案,而非純文字檔案。
如果我們沒有指定模式,讀模式會作為預設的模式。因為從檔案讀到的內容已經以換行符結尾,所以我們在print語句上使用逗號來消除自動換行。最後,我們用close關閉這個檔案。
(42).物件持久化Python提供一個標準的模組,稱為pickle。使用它你可以在一個檔案中儲存任何Python物件,之後你又可以把它完整無缺地取出來。這被稱為 持久地 儲存物件。還有另一個模組稱為cPickle,它的功能和pickle模組完全相同,只不過它是用C語言編寫的,因此要快得多(比pickle快1000倍)。你可以使用它們中的任一個,而我們在這裡將使用cPickle模組。記住,我們把這兩個模組都簡稱為pickle模組程式碼示例import cPickle as p
#import pickle as pshoplistfile = 'shoplist.data'# the name of the file where we will store the objectshoplist = ['apple', 'mango', 'carrot']# Write to the filef = file(shoplistfile, 'w')p.dump(shoplist, f) # dump the object to a filef.close()del shoplist # remove the shoplist# Read back from the storagef = file(shoplistfile)storedlist = p.load(f)print storedlist
使用了import..as語法。這是一種便利方法,類似於SQL中的別名4.異常
(43).使用try..except語句來處理異常。我們把通常的語句放在try-塊中,而把我們的錯誤處理語句放在except-塊中程式碼示例import systry: s = raw_input('Enter something --> ')except EOFError: print '\nWhy did you do an EOF on me?' sys.exit() # exit the programexcept: print '\nSome error/exception occurred.' # here, we are not exiting the program
print 'Done'except從句可以專門處理單一的錯誤或異常,或者一組包括在圓括號內的錯誤/異常。如果沒有給出錯誤或異常的名稱,它會處理 所有的 錯誤和異常。對於每個try從句,至少都有一個相關聯的except從句。

你還可以讓try..except塊關聯上一個else從句。當沒有異常發生的時候,else從句將被執行。
(44).引發異常你可以使用raise語句 引發 異常。你還得指明錯誤/異常的名稱和伴隨異常 觸發的 異常物件。你可以引發的錯誤或異常應該分別是一個Error或Exception類的直接或間接導子類。程式碼示例class ShortInputException(Exception): '''A user-defined exception class.''' def __init__(self, length, atleast): Exception.__init__(self) self.length = length self.atleast = atleast
try: s = raw_input('Enter something --> ') if len(s) < 3: raise ShortInputException(len(s), 3) # Other work can continue as usual hereexcept EOFError: print '\nWhy did you do an EOF on me?'except ShortInputException, x: print 'ShortInputException: The input was of length %d, \ was expecting at least %d' % (x.length, x.atleast)else: print 'No exception was raised.'
在except從句中,提供了錯誤類和用來表示錯誤/異常物件的變數。(45).try..finally
程式碼示例import timetry: f = file('poem.txt') while True: # our usual file-reading idiom line = f.readline() if len(line) == 0: break time.sleep(2) print line,finally: f.close() print 'Cleaning up...closed the file'time.sleep方法可以暫停2秒鐘。程式執行可以手動用ctrl+c暫停

5.python常用的標準庫(46).sys模組sys.argv 命令列引數sys.exit() 退出python程式sys.version/version_info Python的版本資訊sys.stdin、sys.stdout和sys.stderr它們分別對應你的程式的標準輸入、標準輸出和標準錯誤流sys.path python的"classpath"
(47).os模組
這個模組包含普遍的作業系統功能。如果你希望你的程式能夠與平臺無關的話,這個模組是尤為重要的。即它允許一個程式在編寫後不需要任何改動,也不會發生任何問題,就可以在Linux和Windows下執行。一個例子就是使用os.sep可以取代作業系統特定的路徑分割符。
下面列出了一些在os模組中比較有用的部分。它們中的大多數都簡單明瞭。● os.name字串指示你正在使用的平臺。比如對於Windows,它是'nt',而對於Linux/Unix使用者,它是'posix'。● os.getcwd()函式得到當前工作目錄,即當前Python指令碼工作的目錄路徑。● os.getenv()和os.putenv()函式分別用來讀取和設定環境變數。● os.listdir()返回指定目錄下的所有檔案和目錄名。● os.remove()函式用來刪除一個檔案。● os.system()函式用來執行shell命令。比如os.system("ls -all /")● os.linesep字串給出當前平臺使用的行終止符。例如,Windows使用'\r\n',Linux使用'\n'。● os.path.split()函式返回一個路徑的目錄名和檔名。>>> os.path.split('/home/swaroop/byte/code/poem.txt') ('/home/swaroop/byte/code', 'poem.txt')● os.path.isfile()和os.path.isdir()函式分別檢驗給出的路徑是一個檔案還是目錄。● os.path.exists()函式用來檢驗給出的路徑是否真地存在。os.sep獲得當前系統的路徑分割符
6.補充內容
(48).特殊的方法比如__init__和__del__方法,特殊的方法都被用來模仿某個行為。例如,如果你想要為你的類使用x[key]這樣的索引操作(就像列表和元組一樣),那麼你只需要實現__getitem__()方法就可以了。一些特殊的方法
名稱說明
__init__(self,...)這個方法在新建物件恰好要被返回使用之前被呼叫。
__del__(self)恰好在物件要被刪除之前呼叫。
__str__(self)在我們對物件使用print語句或是使用str()的時候呼叫。
__lt__(self,other)當使用 小於 運算子(<)的時候呼叫。類似地,對於所有的運算子
(+,>等等)都有特殊的方法。
__getitem__(self,
key)
使用x[key]索引操作符的時候呼叫。
__len__(self)對序列物件使用內建的len()函式的時候呼叫。

(49).單語句塊程式碼示例if True: print 'Yes'(50).列表綜合
程式碼示例listone = [2, 3, 4]
listtwo = [2*i for i in listone if i > 2]print listtwo滿足條件(if i > 2)的數指定了一個操作(2*i),從而匯出一個新的列表。注意原來的列表並沒有發生變化。在很多時候,我們都是使用迴圈來處理列表中的每一個元素,而使用列表綜合可以用一種更加精確、簡潔、清楚的方法完成相同的工作。(51).在函式中接收元組和列表
當要使函式接收元組或字典形式的引數的時候,有一種特殊的方法,它分別使用*和**字首。這種方法在函式需要獲取可變數量的引數的時候特別有用。程式碼示例def powersum(power, *args): '''Return the sum of each argument raised to specified power.''' total = 0 for i in args: total += pow(i, power) return total
print powersum(2, 3, 4)print powersum(2, 10)
在args變數前有*字首,所有多餘的函式引數都會作為一個元組儲存在args中。如果使用的是**字首,多餘的引數則會被認為是一個字典的鍵/值對。元組*
字典**

(52).lambda
lambda語句被用來建立新的函式物件,並且在執行時返回它們。程式碼示例def make_repeater(n): return lambda s: s*ntwice = make_repeater(2)print twice('word')print twice(5)
lambda需要一個引數,後面僅跟單個表示式作為函式體,而表示式的值被這個新建的函式返回。注意,即便是print語句也不能用在lambda形式中,只能使用表示式(53).exec和eval語句
exec語句用來執行儲存在字串或檔案中的Python語句。例如,我們可以在執行時生成一個包含Python程式碼的字串,然後使用exec語句執行這些語句。下面是一個簡單的例子。exec 'print "Hello World"'eval語句用來計算儲存在字串中的有效Python表示式。下面是一個簡單的例子。eval('2*3')(54).assert語句
assert語句用來宣告某個條件是真的。例如,如果你非常確信某個你使用的列表中至少有一個元素,而你想要檢驗這一點,並且在它非真的時候引發一個錯誤,那麼assert語句是應用在這種情形下的理想語句。當assert語句失敗的時候,會引發一個AssertionError。mylist = ['item']assert len(mylist) >= 1mylist.pop()
assert len(mylist) >= 1(55).repr函式
repr函式用來取得物件的規範字符串表示。反引號(也稱轉換符)可以完成相同的功能。注意,在大多數時候有eval(repr(object)) == object。i = []i.append('item')i['item']repr(i)"['item']"基本上,repr函式和反引號用來獲取物件的可列印的表示形式。你可以通過定義類的__repr__方法來控制你的物件在被repr函式呼叫的時候返回的內容。
7.參考術語表argument 實參attribute 屬性base class 基本類block 塊character 字元class 類comment 註釋complex number 複數derived class 匯出類dictionary 字典escape sequence 轉義符exception 異常expression 表示式field 域float 浮點數function 函式identifier 識別符號indentation 縮排indexing 索引instance 例項integer 整數list 列表list comprehension 列表綜合literal constant 字面意義上的常量logical line 邏輯行long integer 長整數method 方法module 模組namespace 名稱空間object 物件operand 運算元operator 運算子parameter 形參pickle 儲存器physical line 物理行sequence 序列shebang line 組織行slicing 切片statement 語句string 字串subclass 子類superclass 超類tuple 元組type 型別variable 變數

來自為知筆記(Wiz)