Python菜鸟之路:Python基础-类(1)——概念
什么是類?
在python中,把具有相同屬性和方法的對象歸為一個類(class)。類是對象的模板或藍圖,類是對象的抽象化,對象是類的實例化。類不代表具體的事物,而對象表示具體的事物。
類的創建
class Foo:
def bar(self):
pass
第一行定義了類名:語法是class 后面緊接著類的名字,這樣來定義一個類。(Ps:類的名字,首字母,有一個不可文的規定,最好是大寫,這樣需要在代碼中識別區分每個類。)
第二行開始是類的方法,大家看到了,和函數非常相似,但是與普通函數不同的是,它的內部有一個“self”,參數,它的作用是對于對象自身的引用。
類的特點
類對象是多態的:也就是多種形態,這意味著我們可以對不同的類對象使用同樣的操作方法,而不需要額外寫代碼。
類的封裝:封裝之后,可以直接調用類的對象,來操作內部的一些類方法,不需要讓使用者看到代碼工作的細節。
類的繼承:類可以從其它類或者元類中繼承它們的方法,直接使用。
1. 類的封裝
對象里封裝的是一些屬性,而對象的方法封裝在原類里,因此,當需要在其他腳本或模塊中,利用其他腳本或模塊的對象時,需要先導入原模塊或者類。比如我在腳本(1)中定義了A對象,并且通過pickle的方式存儲到文件中,當在腳本(2)需要通過pickle載入文件時,需要先import 腳本1中的類,否則會提示找不到原類。
類的封裝可以封裝類的屬性和類的方法,也可以在對象中封裝對象。比如:
class Foo:
def __init__(self, name, age): #將name和age屬性,封裝到類中
self.name = name
self.age = age
def speak(self, word): # 將speak方法封裝到類中
print("%s say %s" % (self.name, word))
F = Foo(name='諸葛亮', age=18)
F.speak('hello')
out: 諸葛亮 say hello
上邊的__init__和self是什么鬼?
self是Python的類在實例化的時候,自動傳值的東西,代表對象本身。多個對象,則self會在不同對象調用的時候,代表不同對象。
而__init__是類的構造方法,在類進行實例化的時候會自動執行。
2. 類的繼承
類的繼承就是可以從其他類中繼承其他類的方法來使用。
class Human:
def __init__(self):
self.sex = ['man', 'woman']
def eat(self):
print("Human can eat, for example: %s" % self.name)
class Man(Human):
def __init__(self, name, age): #將name和age屬性,封裝到類中
self.name = name
self.age = age
def speak(self, word): # 將speak方法封裝到類中
print("%s say %s" % (self.name, word))
F = Man(name='諸葛亮', age=18)
F.eat() # 調用了父類的eat方法
out:
Human can eat, for example: 諸葛亮
其中Man類是Human類的子類,也叫做派生類。
Human是Man類的父類,也叫做基類。
上邊的代碼實現了簡單的繼承,且繼承關系簡單,只有一個父類, 因此屬于單繼承。另外也有多繼承,即從多個父類繼承。
在使用多繼承的時候, 子類調用父類的方法,如果多個父類無交集,會采用從下到上,從左到右的原則進行匹配。如果多個父類有交集,則采用從下到上, 直至交集前,然后從左到右進行匹配。這種方法叫做“廣度優先”。
這里的從左到右是指,繼承的先后, 比如Foo(Left, Right),那么Left類就是左,優先進行向上查找。
從下到上是指,從Foo類開始查找,然后查找Left類,然后查找Left類的父類直至交集前的最后一層父類。圖示如下:
3. 類的多態
在Python用談多態沒有多大意義,多態的概念是應用于Java和C#這一類強類型語言中。在Java中,在類定義的時候,已經定義好了參數輸入的類型,這與Python中是不同的。但是為了在Java中,支持Python中這樣多種形態的參數輸入形式,就有了多態的用法。它的實現是基于繼承來實現的,用Python偽代碼來表示如下:
class A:
pass
class B(A):
pass
class C(A):
pass
# 要求arg必須是A類型
def func(arg):
pass
#使用繼承的話,就可以按照如下的方式使用
obj1 = B()
obj2 = C()
# 這樣的話,obj1和obj2就可以作為多態參數輸入
func(obj1)
func(obj2)
多態python版
4. Python2 類中的多繼承
在上邊已經介紹了Python3 中類的多繼承為“廣度優先”,那么在Python2中呢?
對于經典類,Python2中的繼承為“深度優先”。
對于新式類,Python2中的繼承為“廣度優先”。
上邊的兩句話怎么理解呢?那么什么是新式類,什么是經典類?
其實很簡單,新式類和經典類的區別,在書寫的時候就能看出來,經典類:class A:.... ; 新式類: class A(object)。可以看出,二者區別就是創建的時候有沒有繼承自object.
如何用代碼測試,請看如下代碼
1 class A:
2 def f1(self):
3 print('A')
4
5 class B(A):
6 def f1(self):
7 print('B')
8
9 class C(A):
10 def f1(self):
11 print('C')
12 class D(B):
13 def f1(self):
14 print('D')
15
16 class E(C):
17 def f1(self):
18 print('E')
19
20 class F(D, E):
21 def f1(self):
22 print('F')
上邊我定義了一種繼承關系。測試步驟如下:
1. 創建F對象
obj = F()
2. 循序漸進調用對象方法
obj.f1()
每次調用obj.f1()都會打印出當前調用的是那個類中的f1方法。接下來修改對應類中的f1函數名,讓f1方法在當前類中無法找到,這樣就會觸發子類去父類中去查找f1方法。多次嘗試之后,可以得出如下的繼承順序圖,從而驗證了,經典類的多繼承關系是深度優先!圖示如下:
Python2 關于新式類的多繼承關系,測試方法同上,最終結果表明:新式類的繼承是“廣度優先”。圖示如下:
:
總結
以上是生活随笔為你收集整理的Python菜鸟之路:Python基础-类(1)——概念的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 坦克300涉水喉连接处会进水吗
- 下一篇: 坦克在哪,车在哪上思维课在哪上