【问题标题】:python: manipulating __dict__ of the classpython:操作类的__dict__
【发布时间】:2011-04-07 18:06:43
【问题描述】:

(全部在 ActivePython 3.1.2 中)

我试图更改类(而不是实例)属性。元类的__dict__ 似乎是完美的解决方案。但是当我尝试修改时,我得到了:

TypeError: 'dict_proxy' 对象确实 不支持物品分配

为什么,我该怎么办?

编辑

我正在类定义中添加属性。

setattr 不起作用,因为该类尚未构建,因此我还不能引用它(或者至少我不知道如何)。

传统的赋值行不通,因为我要添加大量属性,它们的名称是由某个规则确定的(所以我不能随便打出来)。

换句话说,假设我希望class A 具有A.a001A.a999 的属性;并且必须在完全构建之前定义所有这些(否则 SQLAlchemy 将无法正确检测它)。

另请注意,我在原标题中打错了字:我想修改的是普通类的 __dict__,而不是元类。

【问题讨论】:

  • 在这种情况下,您是如何访问 dict 的?
  • 它让我可以访问它,只是不能修改

标签: python-3.x metaclass


【解决方案1】:

按照某些规则创建大量属性听起来像是严重错误。我会回去看看有没有更好的方法。

这里说的是“邪恶代码”(但我认为它会起作用)

class A:
    locals()['alpha'] = 1

print A.alpha

之所以有效,是因为在定义类时,有一个字典可以跟踪您定义的局部变量。这些局部变量最终成为类属性。小心当地人,因为它不一定会“正确”行事。你真的不应该修改本地人,但当我尝试时它似乎确实有效。

【讨论】:

  • 可怕。我想我可以做到,但这似乎是一个 hack。难道没有什么我可以“在船上”做的吗?顺便说一句,这些属性并不多;它们只是在我解析输入时动态创建的。我想也许是什么让这种混乱是来自 SQLAlchemy 的声明性语法
  • 我接受这个答案,因为这是在我的条件下最好的答案......不过我同意,我会放弃声明性语法......
【解决方案2】:

不要使用声明式语法,而是单独构建表,然后在其上使用映射器。请参阅http://www.sqlalchemy.org/docs/05/ormtutorial.html# 我认为在定义类时没有很好的方法将计算属性添加到类。

或者,我不知道这是否可行,但是:

class A(object):
    pass
A.all_my_attributes = values

class B(declarative_base, A):
   pass 

可能会起作用。

【讨论】:

    【解决方案3】:

    我不太熟悉 3 如何处理 dict,但您可以通过简单地像这样继承字典类来规避这个问题:

    class A(dict):
     def __init__(self,dict_of_args):
      self['key'] = 'myvalue'
      self.update(dict_of_args)
      # whatever else you need to do goes here...
    

    A() 可以这样引用:

    d = {1:2,3:4}
    obj = A(mydict)
    print obj['test'],obj[3]  # this will print myvalue and 4
    

    希望这会有所帮助。

    【讨论】:

    • 如果我不必遵循需要使用类属性的 SQLAlchemy 规范,它会起作用。
    猜你喜欢
    • 2011-06-20
    • 2012-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-25
    • 1970-01-01
    相关资源
    最近更新 更多