我必须为具有任意标签集的对象建模。我考虑将标签建模为对象而不仅仅是字符串,因为我希望它们有自己的行为。
例如,标签可以是:
class Jurisdiction():
def __init__(self,name):
self._name = name
#(...)
class EconomicSector():
def __init__(self,name):
self._name = name
#(...)
和变量(对象)可能是农业上的私人支出。我会把它表示为
obj_1 = { EconomicSector("Agriculture"), Jurisdiction("Private")}
# It should be of its own class, but a set of labels will do for now
标签可能有不同的排序,所以我想按惯例定义一个。说,管辖权在经济委员会之前:
order = [Jurisdiction, EconomicSector]
因此,当我想要表示为字符串的对象时,我会得到" Private.Agriculture"而不是" Agriculture.Private"。
问题在于要知道标签的优先级,我必须要求它的类并在类之间进行比较。这违反了OOP原则,因为对象应该是自包含的,并由它响应的消息定义。我不应该处理他们的课程。
通过比较类来获取字符串表示的示例:
obj_1_with_precedence = [(order.index(label.__class__),label) for label in obj_1]
obj_1_sorted = [label_tuple[1] for label_tuple in sorted(obj_1_with_precedence)]
obj_1_with_strings = [label._name for label in obj_1_sorted]
obj_1_as_string = ".".join(obj_1_with_strings)
print(obj_1_as_string) # 'Private.Agriculture'
有没有更好的方法来模拟这个问题,还是应该只是在对象类之间进行比较?
答案 0 :(得分:0)
这就是我要做的。给每个类一个属性,定义它们应该排序的顺序,并定义丰富的比较方法来查看该属性。例如:
from functools import total_ordering
@total_ordering
class Base:
_sort_order = None
def __lt__(self, other):
return self._sort_order < other._sort_order
def __eq__(self, other):
return self._sort_order == other._sort_order
class Jurisdiction(Base):
_sort_order = 1
def __init__(self,name):
self._name = name
#(...)
class EconomicSector(Base):
_sort_order = 2
def __init__(self,name):
self._name = name
#(...)
(如果您尝试比较 Base 的实例和它的一个子类的实例,您会得到一个错误。Base 不应该被实例化。)如果您按照它们应该排序的顺序定义类,你可以定义一个函数来自动给你下一个数字,这样你就不用手动跟踪了,例如:
_id = 0
def _next_sort_id():
global _id
_id += 1
return _id
# definition of Base class
class Jurisdiction(Base):
_sort_order = _next_sort_id()
#(...)
class EconomicSector(Base):
_sort_order = _next_sort_id()
#(...)
如果你想变得更高级,你可以定义一个元类,当你定义一个新的子类时,它会自动分配下一个排序 id,然后你只需要确保你的类以正确的顺序定义并具有正确的基类。