0

_clsクラスの名前を短くすること以外に、mongoengine の値を短くする方法はありますか (コードが読みにくくなります)。

私はこのようなものを探していました:

class User(Document):
    login = StringField(primary_key = True)
    full_name = StringField()
    meta = { "short_class_name": "u" }

class StackOverFlowUser(User):
    rep = IntField()
    meta = { "short_class_name": "s" }

メタ属性が存在する場合short_class_name(しかし、私はそれまたは類似のものを見つけていません)、次のようにすることができます。

{ "_cls" : "s", "_id" : "john",
  "full_name" : "John Smith", "rep" : 600 }

これの代わりに:

{ "_cls" : "User.StackOverFlowUser", "_id" : "john",
  "full_name" : "John Smith", "rep" : 600 }

この例では、これにより約 20% のスペースが節約され、場合によってはさらに大きくなる可能性があります。

mongoengine はオープン ソースだと思います。先に進んでこれをコーディングすることもできますが、より簡単な解決策を知っている場合は、ぜひお聞かせください。

ありがとう。

4

2 に答える 2

1

mongoengine のソース コードを調べた後、私と大部分のMiniQuarkは次のハックを取得しました。

def hack_document_cls_name(cls, new_name):
    cls._class_name = new_name
    from mongoengine.base import _document_registry
    _document_registry[new_name] = cls

またはクラスデコレータとして:

def hack_document_cls_name(new_name):
    def wrapper(cls):
        cls._class_name = new_name
        from mongoengine.base import _document_registry
        _document_registry[new_name] = cls
        return cls
    return wrapper

と を使ってハッキングする以外に方法はありませ_class_name_document_registry

クラスの名前を変更する場合は、クラス定義の直後に (または少なくともサブクラスを定義する前に) このハックを適用する必要があります。そうしない_typesと、基本クラスの長い名前の属性を持つことになります)。例えば:

class User(Document):
    login = StringField(primary_key = True)
    full_name = StringField()

hack_document_cls_name(User, "u")


class StackOverflowUser(User):
    rep = IntField()

hack_document_cls_name(StackOverflowUser, "s")

またはクラスデコレータとして:

@hack_document_cls_name("u")
class User(Document):
    login = StringField(primary_key = True)
    full_name = StringField()


@hack_document_cls_name("s")
class StackOverflowUser(User):
    rep = IntField()
于 2013-04-06T13:37:22.567 に答える
0

わかりました、これまでのところ、私が思いつくことができる最高のものはこれです。それは機能しますが、ハック的な解決策が少ないに違いないと確信しています...

class U(Document): # User
    meta = { "collection": "user" }
    login = StringField(primary_key = True)
    full_name = StringField()

class S(U): # StackOverflowUser
    rep = IntField()

User = U; del(U)
StackOverflowUser = S; del(S)
User.__name__ = "User"
StackOverflowUser.__name__ = "StackOverflowUser"

今私がこれを行うとき:

StackOverflowUser.objects.create(login="john", full_name="John Smith", rep=600)

userコレクションでこのドキュメントを取得します。

{ "_cls" : "U.S", "_id" : "john", "full_name" : "John Smith", "rep" : 600 }

標準の動作と比較すると、これは約 20% の省スペースです。しかし、私はそれがいかにハックであるかが好きではありません。

于 2013-04-06T09:52:25.603 に答える