2

私がこの前の投稿で述べたように。次のことを行うデコレータを作成しようとしています。

装飾されたクラスは、CouchDBやMongoDBなどのドキュメントベースのDB内のドキュメントを表します。デコレータは、そのようなデータベースへのコネクタのインスタンスである引数を受け入れます。モデルクラス(この例ではUser)は、未定義の属性をDB内のフィールドに自動的にマップします。

今、私は少し立ち往生しています:-/上記のものはすべて機能しています。しかし、今はモデルクラスからメソッドを呼び出すことができません。次のエラーが発生します。

TypeError:バインドされていないメソッドmyfunc()は、最初の引数としてUserインスタンスを使用して呼び出す必要があります(代わりに何も取得しません)

class Connector(object):
    def readvar(self, var):
        data = {"emailAddress":"jack.bauer@ctu.org", "lastName":"Bauer"}
        return data[var]

class DocumentDB(object):
    def __init__(self,connector):
        self.connector = connector

    def __call__(self, *args, **kargs):
        _c = self.connector

        class TransparentAttribute:         
            def __getattr__(self, attrname):
                try:
                    return _c.readvar(attrname)
                except:
                    return getattr(args[0], attrname)
        return TransparentAttribute

c = Connector()
@DocumentDB(c)
class User(object):

    username = "JackBauer"
    def doSomething(self):
        print "bla bla"
    def doSomethingElse(self):
        pass
    def myfunc(self):
        print "afadsadsf adsf asdf asdf"

u = User()
u.myfunc() # Does not work!!!
print u.emailAddress
print u.lastName
print u.username
4

2 に答える 2

1

args[0]Userクラスオブジェクトであり、例外としてインスタンスではありません。したがって、バインドされたメソッドではなく、バインドされていないメソッド(別名クラスメソッド)を取得します。

@DocumentDB(c)
class User(object):
    pass

次のように書き直すことができます

class User(object):
    pass
User = DocumentDB(c)(User)

これにより、問題がより明確になります(ところで、TransparentAttribute意図的に継承しませんobjectか?)

デコレータではなくConnector、追加の基本クラスとして使用することで、必要なものを取得できるかもしれませUserん。

于 2013-01-16T07:17:36.520 に答える
1

簡単に遊んだことがありますが、ユーザーのサブクラス化が機能しているようです。

class DocumentDB(object):
    def __init__(self,connector):
        self.connector = connector

    def __call__(self, user):
        _c = self.connector

        print self, user, _c # <__main__.DocumentDB object at 0x012DAD30> <class '__main__.User'> <__main__.Connector object at 0x012DAD70>

        class TransparentAttribute(user):
            def __getattr__(self, attrname):
                try:
                    return _c.readvar(attrname)
                except:
                    return getattr(user, attrname)

        return TransparentAttribute

u = User()
print type(u) # <class '__main__.TransparentAttribute'>
u.myfunc() # afadsadsf adsf asdf asdf

の後u = User()uはタイプがありTransparentAttribute、サブクラス化しない場合は、基本的にUserインスタンスをインスタンスに置き換えますTransparentAttribute(したがって、すべてのUserオブジェクトのローカル関数はなくなります)。

(しかし、正直なところ、これのいくつかは私の頭の上に少しあります-私を修正してください)

于 2013-01-16T07:18:24.187 に答える