[英]Python: overlapping (non exclusive) inheritance to have methods available based on instance parameters
如果參數滿足特定條件,我希望某些屬性和方法僅在類實例中可用。 不同的情況不是唯一的。 我已經有了一個可行的解決方案(包括 ShadowRanger 的建議):
class polygon():
def __new__(cls, vert, axis=None):
triangle = vert == 3
solidrev = axis is not None
if triangle and not solidrev:
return super().__new__(_triangle)
elif solidrev and not triangle:
return super().__new__(_solid)
elif solidrev and triangle:
return super().__new__(_triangle_solid)
else:
return super().__new__(cls)
def __init__(self, vert, axis=None):
self.polygon_attribute = 1
def polygon_method(self):
print('polygon')
class _triangle(polygon):
def __init__(self, vert, axis=None):
super().__init__(vert, axis)
self.triangle_attribute = 2
def triangle_method(self):
print('triangle')
class _solid(polygon):
def __init__(self, vert, axis):
super().__init__(vert, axis)
self.solid_attribute = 3
def solid_method(self):
print('solid of revolution')
class _triangle_solid(_triangle, _solid):
def __init__(self, vert, axis):
super().__init__(vert, axis)
屬性和方法的可用性取決於實例參數:
所有組合:
P = polygon(2)
P = polygon(2,axis=0)
P = polygon(3)
P = polygon(3,axis=0)
有沒有更優雅的方法來做到這一點? 在理想情況下,我想擺脫 _triangle_solid 類。 另外,我不明白為什么我需要在某些情況下而不是所有情況下為 axis 定義默認參數。
完整項目: https ://github.com/gerritnowald/polygon
這是一個試圖過度使用繼承的例子。 當子類與其父類之間存在“是”關系時,繼承在邏輯上是有意義的。 三角形是多邊形,所以沒有問題; 這是一個合理的繼承鏈。 旋轉實體雖然可能由多邊形構建,但它不是多邊形,並且試圖將其楔入繼承層次結構會產生問題。 更糟糕的是,旋轉實體甚至可能根本無法根據多邊形來定義。
我強烈建議使用代表正在旋轉以產生它的任何屬性來定義您的旋轉實體,而不是作為該旋轉圖形的子類。
話雖如此, polygon
本身不應該負責知道它的所有子類,如果是,它仍然應該是三角形的父類。 您當前呈現的設計有一個polygon
類,沒有任何東西是其實例; __new__
返回的不是polygon
的東西,這讓人很困惑。 您可以通過以下方式以更安全的方式編寫層次結構,即使仍然不是慣用的 OO 方式:
# Tweaked name; it's not just the base anymore; using PEP8 class name capitalization rules
class Polygon:
def __new__(cls, vert, *args, **kwargs): # Accept and ignore the arguments we don't care
# about, __init__ will handle them
if vert == 3:
return super().__new__(Triangle)
else:
return super().__new__(cls)
def __init__(self, vert, axis):
self.polygon_attribute = 1
def polygon_method(self):
print('polygon')
class Triangle(Polygon):
def __init__(self, vert, axis):
super().__init__(vert, axis)
self.triangle_attribute = 2
def triangle_method(self):
print('triangle')
t = Polygon(3, None)
p = Polygon(4, None)
print(type(t), type(p))
# Indicates t is a Triangle, p is a Polygon
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.