Python class 抽象類 與 元類 詳解

2021-08-15 20:26:57 字數 3071 閱讀 7618

要定義抽象基類,需要使用abc模組。該模組定義了乙個元類(abcmeta)和一組裝飾器@abstractmethod,@abstractproperty。可以按如下方式使用

from abc import abcmeta,abstractmethod,abstractproperty

class

people:

__metaclass__ = abcmeta

@abstractmethod

defset_name

(self):

pass

@abstractproperty

defpro

(self):

pass

要定義抽象類,需要將元類設定為abcmeta。這一步是必須的,因為抽象類的實現離不開元類。在抽象類中,@abstractmethod和@abstractproperty裝飾的方法/特性其子類必須實現。

抽象類並不能直接例項化。

f = people()  #typeerror: can't instantiate abstract class student with abstract methods pro, set_name
這一限制也適用於派生類。如果類foo1繼承了foo,但是foo1沒有實現foo中的抽象方法,當建立foo1的例項時,會生成類似的錯誤。

class

student

(people):

pass

f = student() #typeerror: can't instantiate abstract class student with abstract methods pro, set_name

儘管抽象類會在實現的方法和特性上強制實施規則,但它不會對引數和返回值進行一致性檢查。所以,抽象類不會檢查子類是否使用了與抽象方法相同的引數和返回值。

雖然抽象類無法例項化,但是它可以決定子類中必須實現的方法和特性。而且,基類中的抽象方法/特性仍然可以從子類中呼叫。

class

student

(people):

defset_name

(self,name):

#引數個數不同

print super(student,self).set_name()#呼叫基類中的抽象方法

print

'student,set_name = %s'%name

return

true

#返回值不同

defpro

(self,tmp = ''):

#引數不同,特性->方法也是可以的,因為特性是一種特殊的函式

print super(student,self).pro #呼叫基類中的特性

print

'student,pro,tmp = %s'%tmp

return

true

#返回值不同

>>> f = student()

>>> f.set_name('xiaohong')

none

student,set_name = xiaohong

>>> f.pro()

none

student,pro,tmp = null

抽象基類支援對已經存在的類進行註冊,使其屬於該基類,使用register()進行註冊。

如向抽象基類a註冊類b,a.register(b)

向抽象基類註冊某個類時,對於註冊類的例項,涉及抽象基類的型別檢查操作(isinstance,issubclass)將返回true。

向抽象類註冊某個類時,不會檢查該類是否實現了抽象方法/特性。這種註冊只影響型別檢查,它不會向註冊的類進行額外的錯誤檢查。

from abc import abcmeta,abstractmethod,abstractproperty

class

people

(object):

__metaclass__ = abcmeta

@abstractmethod

defset_name

(self):

pass

class

foo(object):

#沒有實現抽象方法set_name

pass

#print people,type(people),type(type(people)),people.__metaclass__

#print foo,type(foo),type(type(foo))

f = foo()

print isinstance(f,people) #false

print isinstance(f,foo) #true

print issubclass(foo,people) #false

print issubclass(foo,object) #true

print issubclass(people,object)#true

people.register(foo) #向people抽象基類註冊,讓foo屬於people

print isinstance(f,people) #true

print isinstance(f,foo) #true

print issubclass(foo,people) #true

print issubclass(foo,object) #true

print issubclass(people,object)#true

python的內建型別組織到乙個相對扁平的層次結構中。如int,float,可以看到他們直接繼承自所有物件的根(object),而不是表示數字的中間基類。因此很難編寫程式來根據型別檢查和操作物件。抽象類機制解決了這一難題,它允許將已存在的物件組織到使用者定義的型別層次結構中。

抽象類與抽象函式

1 抽象函式 只有函式定義,沒有函式體的函式。例如 abstract void fun 2 抽象類 基類 使用abstract定義的類稱之為抽象類。記住 抽象類天生就是當爹的,要被繼承!1 抽象類不能生成物件 假設可以生成物件,那麼可以呼叫裡面的抽象函式,而抽象類中若是有乙個抽象 函式,其函式體為空...

抽象類與抽象方法

有些類注定是不能被初始化的,即不能被new 設想一下,乙個animal類下有很多子類,dog,cat,lion等,這些子類都可以被例項化,但是animal如果被例項化後會變成什麼樣?會有什麼特徵?這是難以想象的,因此像animal這樣的父類就不能例項化,我們迫切需要有一種類,只能例項化其子類物件而本...

抽象類與抽象方法

l 抽象類與抽象方法由abstract修飾 l abstract的使用注意 抽象方法沒有方法體 抽象成員只能存在於抽象類中 抽象類可以有非抽象成員 抽象類的派生類必須實現抽象方法體 抽象類只能用作基類,無法例項化 static void main string args public abstrac...