我正在尝试创建一组类,其中每个类都有相应的类的“数组”版本。但是,我需要两个类都相互了解。这是一个工作示例,以演示我正在尝试做的事情。但这需要在每个类中复制一个“ to_array”。在我的实际示例中,即使唯一的区别是“ BaseArray”,“ PointArray”或“ LineArray”,也需要重复其他更复杂的方法。类似地,BaseArray类将具有仅“ BaseObj”,“ PointObj”或“ LineObj”不同的方法。
# ------------------
# Base object types
# ------------------
class BaseObj(object):
def __init__(self, obj):
self.obj = obj
def to_array(self):
return BaseArray([self])
class Point(BaseObj):
def to_array(self):
return PointArray([self])
class Line(BaseObj):
def to_array(self):
return LineArray([self])
# ------------------
# Array object types
# ------------------
class BaseArray(object):
def __init__(self, items):
self.items = [BaseObj(i) for i in items]
class PointArray(BaseArray):
def __init__(self, items):
self.items = [Point(i) for i in items]
class LineArray(BaseArray):
def __init__(self, items):
self.items = [Line(i) for i in items]
# ------------------
# Testing....
# ------------------
p = Point([1])
print(p)
pa = p.to_array()
print(pa)
print(pa.items)
这是我的尝试,可以理解的是会引起一个错误。我知道为什么会收到NameError,因此我知道为什么这不起作用。我正在显示这是为了弄清楚我想做什么。
# ------------------
# Base object types
# ------------------
class BaseObj(object):
ArrayClass = BaseArray
def __init__(self, obj):
self.obj = obj
def to_array(self):
# By using the "ArrayClass" class attribute here, I can have a single
# "to_array" function on this base class without needing to
# re-implement this function on each subclass
return self.ArrayClass([self])
# In the actual application, there would be other BaseObj methods that
# would use self.ArrayClass to avoid code duplication
class Point(BaseObj):
ArrayClass = PointArray
class Line(BaseObj):
ArrayClass = LineArray
# ------------------
# Array object types
# ------------------
class BaseArray(object):
BaseType = BaseObj
def __init__(self, items):
self.items = [self.BaseType(i) for i in items]
# In the actual application, there would be other BaseArray methods that
# would use self.BaseType to avoid code duplication
class PointArray(BaseArray):
BaseType = Point
class LineArray(BaseArray):
BaseType = Line
# ------------------
# Testing....
# ------------------
p = Point([1])
print(p)
pa = p.to_array()
print(pa)
print(pa.items)
一种可能的解决方案是仅对所有类将“ ArrayClass”定义为“无”,然后在定义“数组”版本之后,您可以像这样对原始类进行猴子修补:
BaseObj.ArrayClass = BaseArray
Point.ArrayClass = PointArray
Line.ArrayClass = LineArray
这可行,但是感觉有点不自然,我怀疑有更好的方法来实现。万一重要,我的用例最终将是(仍然)仍然使用Python 2.7的程序的插件,因此我需要一个使用Python 2.7的解决方案。理想情况下,相同的解决方案可以在2.7和3+中运行。
答案 0 :(得分:0)
这里是使用装饰器的解决方案。我更喜欢使用类属性分配(如我所说的“ monkey patch”),因为它可以使事情保持一致和清晰。我对此很满意,但仍然对其他想法感兴趣...
# ------------------
# Base object types
# ------------------
class BaseObj(object):
ArrayClass = None
def __init__(self, obj):
self.obj = obj
def to_array(self):
# By using the "ArrayClass" class attribute here, I can have a single
# "to_array" function on this base class without needing to
# re-implement this function on each subclass
return self.ArrayClass([self])
# In the actual application, there would be other BaseObj methods that
# would use self.ArrayClass to avoid code duplication
@classmethod
def register_array(cls):
def decorator(subclass):
cls.ArrayClass = subclass
subclass.BaseType = cls
return subclass
return decorator
class Point(BaseObj):
pass
class Line(BaseObj):
pass
# ------------------
# Array object types
# ------------------
class BaseArray(object):
BaseType = None
def __init__(self, items):
self.items = [self.BaseType(i) for i in items]
# In the actual application, there would be other BaseArray methods that
# would use self.BaseType to avoid code duplication
@Point.register_array()
class PointArray(BaseArray):
pass
@Line.register_array()
class LineArray(BaseArray):
pass
# ------------------
# Testing....
# ------------------
p = Point([1])
print(p)
pa = p.to_array()
print(pa)
print(pa.items)