python - 将类实例合并到Python中的另一个实例中?

标签 python join instance persistent chain

我正在设计一种类似“拼图游戏”的工具来管理不同的水管(例如零件组合)以获得乐趣。

  1. 我有不同用途的不同单一部件类型(冷却器、加热器、净化器...)
  2. 那些不同接口(interface)尺寸的部件可以相互连接(1/4英寸。1/6英寸......)

我希望这些部件可以存储在数据库中,并且可以组合成一个全新的部件组合(随机或有意),但仍然可以被视为一个功能部件。

这是初步的想法

class MetaInfo():
    def __init__(self, name, intype,outtype,shape,serialno):
        this.name = name
        this.intype = intype
        this.outtype = outtype
        this.shape = shape
        this.sn = serialno


def parts():
    def __init__(self, meta):
        this.meta = meta

def linkwith(self, part):
    if part.meta.shape == this.meta.shape: 
    # make it simple, logical here is just same shape can be connected each other 
        return ???         # a new parts combination 
    else:
        raise Error 

m1 = MetaInfo("cooler", "hotwater", "coldwater", "1/4 inch round", "SN:11111" )
m2 = MetaInfo("heater", "coldwater", "hotwater", "1/4 inch round", "SN:22222" )
m3 = MetaInfo("purifier", "coldwater", "hotwater", "1/6 inch round", "SN:33333" )


a = parts(m1)
b = parts(m2)
c = parts(m3)

以下是我需要您帮助的内容:

  1. 如何将 m1、m2、m3 保存为可以持久保存在人类可读数据库中的列表,下次只需更改该数据库本身我就可以添加元?

  2. 如何将不同的部分链接成一个新的组合?比如

    e = a.linkwith(b)
    d = c.linkwith(a)
    

    并将其也存储在该数据库中?

  3. 我可以制作一条长链,制作一个新的零件实例,例如

    f = c.linkwith(a,b,d,e)
    

并轻松找出该链中哪个部分无法链接,这里的 c 部分具有不同的大小?

非常感谢。

最佳答案

我很无聊。这很粗糙,但很有效。如果您已经了解得够多了,您将需要使用数据库;但我理解想要使用人类可读的格式。

from copy import copy
import csv

class Part_Base(object):
    pass

class MultiPart_Base(list):
    pass

class part_meta(type):
    part_names = {}
    parts      = []
    def __init__(cls, cls_name, cls_bases, cls_dict):
        super(part_meta, cls).__init__(cls_name, cls_bases, cls_dict)
        if(not Part_Base in cls_bases):
            part_meta.part_names[cls_name] = cls

    def __call__(self, *args, **kwargs):
        name = kwargs.get("name", "")
        if(part_meta.part_names.has_key(name) and not (self is part_meta.part_names[name])):
            obj = part_meta.part_names[name].__call__(*args, **kwargs)
        else:
            obj = None
            if(not part_meta.part_names.has_key(self.__name__)):
                new_class = part_meta(name, (Generic_Part,), {})
                globals()[name] = new_class
                obj = new_class(*args, **kwargs)
            else:
                obj = super(part_meta, self).__call__(*args, **kwargs)
        if not obj in part_meta.parts:
            part_meta.parts.append(obj)
        return obj

    @classmethod
    def save(cls):
        all_fields = list(reduce(lambda x, y: x | set(y.fields), cls.parts, set([])))
        with open("parts.csv", "w") as file_h:
            writer = csv.DictWriter\
            (
                file_h,
                all_fields,
                restval        = "",
                extrasaction   = "ignore",
                dialect        = "excel",
                lineterminator = "\n",

            )
            writer.writeheader()
            for part in cls.parts:
                writer.writerow({field : getattr(part, field) for field in part.fields})

    @classmethod
    def load(cls):
        with open("parts.csv", "r") as file_h:
            reader = csv.DictReader(file_h)
            for row in reader:
                Part(**row)

class Part(Part_Base):
    __metaclass__ = part_meta
    fields        = []
    def __init__(self, **kwargs):
        for name, value in kwargs.items():
            setattr(self, name, value)
        self.fields += kwargs.keys()

    def __repr__(self):
        return "<%s>" % self.description

    @property
    def description(self):           
        return "%s: %s %s %s %s" % (self.name, self.intype, self.outtype, self.shape, self.serialno)

    def linkwith(self, *parts):
        return Generic_MultiPart(self, *parts)

class Generic_Part(Part):
    def __init__(self, **kwargs):
        kwargs["name"] = self.__class__.__name__
        super(Generic_Part, self).__init__(**kwargs)

class Generic_MultiPart(MultiPart_Base):
    def __init__(self, *parts):
        super(Generic_MultiPart, self).__init__()
        if len(parts) >= 2:
            self.shape = parts[0].shape
            self.linkwith(*parts)
        else:
            raise ValueError("Not enough parts")

    def __repr__(self):
        return "<MultiPart: %s>" % super(Generic_MultiPart, self).__repr__()

    def linkwith(self, *parts):
        for part in parts:
            if part.shape == self.shape:
                if isinstance(part, Part):
                    self.append(part)
                elif isinstance(part, MultiPart_Base):
                    self.extend(part)
            else:
                raise ValueError("Incompatible parts")
        return self

class cooler(Generic_Part):
    intype  = "hotwater"
    outtype = "coldwater"
    fields  = ["intype", "outtype"]

class heater(Generic_Part):
    intype  = "coldwater"
    outtype = "hotwater"
    fields  = ["intype", "outtype"]

def make_some_parts():
    some_parts = \
    [
        # This is actually a cooler object
        # The metaclass uses the cooler class from above
        # to create the object
        Part
        (
            name     = "cooler",
            shape    = "1/4 inch round",
            serialno = "SN:11111"
        ),
        # Using the heater class directly
        heater
        (
            shape    = "1/4 inch round",
            serialno = "SN:22222"
        ),
        Part
        (
            name     = "purifier",
            intype   = "coldwater",
            outtype  = "hotwater",
            shape    = "1/6 inch round",
            serialno = "SN:33333"
        ),
        Part
        (
            name     = "carbon_filter",
            intype   = "coldwater",
            outtype  = "coldwater",
            shape    = "1/4 inch round",
            serialno = "SN:33333"
        )
    ]

    useless_part = some_parts[0].linkwith(some_parts[1])
    print useless_part
    filter_part  = copy(useless_part).linkwith(some_parts[3])
    print filter_part

    part_meta.save()

def load_some_parts():
    part_meta.load()
    print part_meta.parts

您可以手动编辑parts.csv(在Excel或其他格式中),它将生成所描述的零件。 保存/恢复功能尚未扩展到 MultiParts;你可以做到。

关于python - 将类实例合并到Python中的另一个实例中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23191712/

相关文章:

python - 通过 Python 和 smtplib 发送 Verizon SMS 消息

java - Java对象的实例大小在不同的JVM中是不同的

java - 为什么静态字段没有序列化

python - 类型错误 : geturl() takes exactly 1 argument (2 given)

python - Python 装饰器的参数

php - 如何在mysql和php中连接两个具有共同属性的表?

ruby-on-rails - 一般 Active Record 加入或包含

PostgreSQL:RANGE 数据类型上的 FULL OUTER JOIN

java - 为什么我不能实例化这样的对象?

python - redisai 客户端密码/认证过程