Python Decorative Class不允许方法调用。为什么?

时间:2013-01-16 06:25:26

标签: python class methods couchdb decorator

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

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

现在我陷入了困境: - /提到的事情都在发挥作用。但现在我无法调用模型类中的任何方法。我收到以下错误。

  

TypeError:必须使用User实例调用未绑定方法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

2 个答案:

答案 0 :(得分:1)

args[0]User类对象,不是你的实例,因此你得到一个未绑定的方法(也就是类方法)而不是绑定方法。

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

可以改写为

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

这使得问题更加明确(顺便说一下,TransparentAttribute是否故意不从object继承?)

也许你可以通过使用Connector作为User的附加基类来获得你不想要的东西?

答案 1 :(得分: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实例替换为{{1}实例(因此所有User对象的本地函数都消失了)。

(但说实话,这有点过头了 - 随意纠正我)