ตามที่อธิบายไว้ในคำตอบอื่น ๆ ใช่คุณสามารถใช้คลาสนามธรรมในหลามใช้โมดูลabc
ด้านล่างนี้ผมให้เป็นตัวอย่างที่เกิดขึ้นจริงโดยใช้นามธรรม@classmethod
, @property
และ@abstractmethod
(โดยใช้ Python 3.6 ขึ้นไป) สำหรับฉันมันเป็นเรื่องง่ายกว่าที่จะเริ่มต้นด้วยตัวอย่างที่ฉันสามารถคัดลอก & วางได้อย่างง่ายดาย ฉันหวังว่าคำตอบนี้จะเป็นประโยชน์สำหรับผู้อื่น
ก่อนอื่นให้สร้างคลาสฐานที่เรียกว่าBase
:
from abc import ABC, abstractmethod
class Base(ABC):
@classmethod
@abstractmethod
def from_dict(cls, d):
pass
@property
@abstractmethod
def prop1(self):
pass
@property
@abstractmethod
def prop2(self):
pass
@prop2.setter
@abstractmethod
def prop2(self, val):
pass
@abstractmethod
def do_stuff(self):
pass
ของเราBase
ระดับมักจะมีfrom_dict
classmethod
การproperty
prop1
(ซึ่งก็คืออ่านอย่างเดียว) และproperty
prop2
(ซึ่งยังสามารถตั้งค่า) do_stuff
เช่นเดียวกับฟังก์ชั่นที่เรียกว่า ไม่ว่าคลาสใดที่ถูกสร้างขึ้นโดยBase
จะต้องใช้สิ่งเหล่านี้ทั้งหมดสำหรับเมธอด / คุณสมบัติ โปรดทราบว่าสำหรับวิธีการที่จะเป็นนามธรรมสองตกแต่งจะต้อง - และนามธรรมclassmethod
property
ตอนนี้เราสามารถสร้างคลาสA
เช่นนี้:
class A(Base):
def __init__(self, name, val1, val2):
self.name = name
self.__val1 = val1
self._val2 = val2
@classmethod
def from_dict(cls, d):
name = d['name']
val1 = d['val1']
val2 = d['val2']
return cls(name, val1, val2)
@property
def prop1(self):
return self.__val1
@property
def prop2(self):
return self._val2
@prop2.setter
def prop2(self, value):
self._val2 = value
def do_stuff(self):
print('juhu!')
def i_am_not_abstract(self):
print('I can be customized')
วิธีการที่จำเป็นทั้งหมด / คุณสมบัติจะดำเนินการและเราสามารถ - แน่นอน - ยังเพิ่มฟังก์ชั่นเพิ่มเติมที่ไม่ได้เป็นส่วนหนึ่งของBase
(ที่นี่: i_am_not_abstract
)
ตอนนี้เราสามารถทำได้:
a1 = A('dummy', 10, 'stuff')
a2 = A.from_dict({'name': 'from_d', 'val1': 20, 'val2': 'stuff'})
a1.prop1
# prints 10
a1.prop2
# prints 'stuff'
ตามที่ต้องการเราไม่สามารถตั้งค่าprop1
:
a.prop1 = 100
จะกลับมา
AttributeError: ไม่สามารถตั้งค่าแอตทริบิวต์
ด้วยfrom_dict
วิธีการของเราก็ใช้งานได้ดี:
a2.prop1
# prints 20
ถ้าเรากำหนดคลาสที่สองเป็นB
ดังนี้:
class B(Base):
def __init__(self, name):
self.name = name
@property
def prop1(self):
return self.name
และพยายามยกตัวอย่างวัตถุเช่นนี้:
b = B('iwillfail')
เราจะได้รับข้อผิดพลาด
TypeError: ไม่สามารถยกตัวอย่างคลาสนามธรรม B ด้วยเมธอด abstract do_stuff, from_dict, prop2
รายชื่อทุกสิ่งที่กำหนดไว้ในที่ที่เราไม่ได้ใช้ในBase
B