3

X と Y の 2 つのクラスがあるとします。クラスに属性を追加してこれらのクラスを修飾し、新しいクラス X1 と Y1 を作成します。

例えば:

class X1(X):
  new_attribute = 'something'

class Y1(Y):
  new_attribute = 'something'

new_attributeは、X1 と Y1 の両方で常に同じになります。X と Y は、多重継承が不可能であることを除いて、意味のある方法で関連付けられていません。他にも一連の属性がありますが、これは説明のために縮退しています。

私はこれを複雑にしすぎているように感じますが、デコレータを使用することを考えていました。

def _xywrap(cls):
  class _xy(cls):
    new_attribute = 'something'
  return _xy

@_xywrap(X)
class X1():
   pass

@_xywrap(Y)
class Y1():
   pass

かなり一般的なパターンが欠けているように感じます。考え、意見、フィードバックをいただければ幸いです。

読んでくれてありがとう。

ブライアン

編集:例:

これは、明らかになる可能性のある関連する抜粋です。一般的なクラスは次のとおりです。

from google.appengine.ext import db

# I'm including PermittedUserProperty because it may have pertinent side-effects
# (albeit unlikely), which is documented here: [How can you limit access to a
# GAE instance to the current user][1].

class _AccessBase:
   users_permitted = PermittedUserProperty()
   owner = db.ReferenceProperty(User)

class AccessModel(db.Model, _AccessBase):
    pass

class AccessExpando(db.Expando, _AccessBase):
    pass

# the order of _AccessBase/db.* doesn't seem to resolve the issue
class AccessPolyModel(_AccessBase, polymodel.PolyModel):
    pass

サブドキュメントは次のとおりです。

 class Thing(AccessExpando):
     it = db.StringProperty()

Thing には次のプロパティがある場合があります。

 Thing { it: ... }

その他の場合:

 Thing { it: ..., users_permitted:..., owner:... }

Thing に _AccessParent プロパティがある場合とない場合がある理由を理解できませんでした。

4

3 に答える 3

5

3引数タイプを使用します:

def makeSomeNicelyDecoratedSubclass(someclass):
  return type('MyNiceName', (someclass,), {'new_attribute':'something'})

ご想像のとおり、これは確かにかなり人気のあるイディオムです。

編集:一般的なケースでは、someclassにカスタムメタクラスがある場合、それを保持するために、それ自体typeの代わりに(1引数で)抽出して使用する必要がありtypeます(これは、DjangoおよびApp Engineモデルの場合です):

def makeSomeNicelyDecoratedSubclass(someclass):
  mcl = type(someclass)
  return mcl('MyNiceName', (someclass,), {'new_attribute':'something'})

これは、上記のより単純なバージョンが機能する場合にも機能します(単純な場合、カスタムメタクラスがないためtype(someclass) is type)。

于 2009-09-12T00:58:23.797 に答える
3

voyager's answerに関するコメントへの返信:

from google.appengine.ext import db

class Mixin(object):
    """Mix in attributes shared by different types of models."""
    foo = 1
    bar = 2
    baz = 3

class Person(db.Model, Mixin):
    name = db.StringProperty()

class Dinosaur(db.polymodel.PolyModel, Mixin):
    height = db.IntegerProperty()

p = Person(name='Buck Armstrong, Dinosaur Hunter')
d = Dinosaur(height=5000)

print p.name, p.foo, p.bar, p.baz
print d.height, d.foo, d.bar, d.baz

実行すると、

Buck Armstrong, Dinosaur Hunter 1 2 3
5000 1 2 3

それはあなたが念頭に置いていたことではありませんか?

于 2009-09-11T19:33:21.887 に答える
2

多重継承が使えないのはなぜですか?

class Origin:
  new_attribute = 'something'

class X:
  pass

class Y:
  pass

class X1(Origin, X):
  pass

class Y1(Origin, Y):
  pass
于 2009-09-11T17:43:37.953 に答える