【问题标题】:Python Decorated Class does not allow method calls. Why?Python 装饰类不允许方法调用。为什么?
【发布时间】:2023-04-05 06:15:01
【问题描述】:

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

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

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

TypeError:未绑定的方法 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

【问题讨论】:

  • 您能否显示错误的完整回溯,包括它发生的行?
  • @DavidRobinson 我运行了相同的代码,得到了简单的Traceback (most recent call last): File "<module1>", line 52, in <module> TypeError: unbound method myfunc() must be called with User instance as first argument (got nothing instead)(在线u.myfunc()

标签: python class methods couchdb decorator


【解决方案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 实例(因此所有用户对象的本地功能消失了)。

(但老实说,其中一些内容让我有点想不通 - 请随时纠正我)

【讨论】:

    【解决方案2】:

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

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

    可以改写为

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

    这让问题更清楚了(顺便说一句,TransparentAttribute 是否故意不继承自 object?)

    也许您可以通过使用Connector 作为User 的附加基类而不是使用装饰器来获得您想要的东西?

    【讨论】:

      猜你喜欢
      • 2022-01-19
      • 1970-01-01
      • 2011-07-08
      • 2021-06-26
      • 1970-01-01
      • 1970-01-01
      • 2021-07-20
      • 2017-10-12
      • 2010-12-31
      相关资源
      最近更新 更多