正如我在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
答案 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对象的本地函数都消失了)。
(但说实话,这有点过头了 - 随意纠正我)