2

正如我在上一篇文章中提到的。我试图创建一个装饰器,它执行以下操作:

装饰类表示基于文档的数据库(如 CouchDB 或 MongoDB)中的文档。Decorator 接受 on 参数,该参数是此类数据库的连接器实例。模型类(在此示例中为用户)会自动将未定义的属性映射到数据库中的字段。

现在我有点卡住了:-/提到的东西都在工作。但现在我不能从模型类中调用任何方法。我收到以下错误。

类型错误:必须使用用户实例作为第一个参数调用未绑定的方法 myfunc()(什么都没有)

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是 type TransparentAttribute,我认为如果你不继承它,那么你基本上用一个实例替换你UserTransparentAttribute实例(所以所有 User 对象的本地函数都消失了)。

(但老实说,其中一些让我有点过头了——请随时纠正我)

于 2013-01-16T07:18:24.187 回答