开发者

python: manipulating __dict__ of the class

(All in ActivePython 3.1.2)

I tried to change the class (rather than instance) attributes. The __dict__ of the metaclass seemed like the perfect solution. But when I tried to modify, I got:

TypeError: 'dict_proxy' object does not support item assignment

Why, and what can I do about it?

EDIT

I'm adding attributes inside the class definition.

setattr doesn't work because the class is not yet built, and hence I can't refer to it yet (or at least I don't know how).

T开发者_Python百科he traditional assignment doesn't work because I'm adding a large number of attributes, whose names are determined by a certain rule (so I can't just type them out).

In other words, suppose I want class A to have attributes A.a001 through A.a999; and all of them have to be defined before it's fully built (since otherwise SQLAlchemy won't instrument it properly).

Note also that I made a typo in the original title: it's __dict__ of a regular class, not a metaclass, that I wanted to modify.


The creation of a large number of attributes following some rule smells like something is seriously wrong. I'd go back and see if there isn't a better way of doing that.

Having said there here is "Evil Code" (but it'll work, I think)

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

print A.alpha

This works because while the class is being defined there is a dictionary that tracks the local variables you are definining. These local variables eventually become the class attributes. Be careful with locals as it won't necessarily act "correctly." You aren't really supposed to be modifying locals, but it does seem to work when I tried it.


Instead of using the declarative syntax, build the table seperately and then use mapper on it. see http://www.sqlalchemy.org/docs/05/ormtutorial.html# I think there is just no good way to add computed attributes to class while defining it.

Alternatively, I don't know whether this will work but:

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

class B(declarative_base, A):
   pass 

might possibly work.


I'm not too familiar with how 3 treats dict but you might be able to circumvent this problem by simply inheriting the dictionary class like so:

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() can be referenced like so:

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

Hope this helps.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜