egbert a écrit :
Normally you use setattr() if the name of the attribute is in a
namestring:
setattr(self, namestring, value)
But my attributes are lists or dictionaries, and I don't seem to be
able to use setattr anymore.

Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41)
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class Foo(object):
...   def __init__(self):
...     self.attr1 = {}
...     self.attr2 = []
...
>>> attr1 = dict((x, x) for x in 'abc')
>>> attr2  = range(5)
>>> f = Foo()
>>> setattr(f, "attr1", attr1)
>>> setattr(f, "attr2", attr2)
>>> f.attr1
{'a': 'a', 'c': 'c', 'b': 'b'}
>>> f.attr2
[0, 1, 2, 3, 4]
>>>


Either I failed to understand you or you overlooked some other problem in you code and jumped to the wrong conclusions.


Now I use for a list something like:
self.__dict__[namestring].append(value)
and for a dictionary:
self.__dict__[namestring][keystring]=value

Duh. You're confusing *setting* an attribute and *getting it then mutating it*.

Can you get the difference between:

>>> f.attr2.append(42)

and

>>> f.attr2 = [7, 87, 98]

?

If you don't, then you're in for serious trouble :-/


But I have the impression that I am cheating, because users should not
operate on __dict__ directly.

Client code shouldn't mess with implementation attribute, for sure. This bypasses all the lookup rules, and can break computed attributes (ie properties or other custom descriptors). At least use getattr() and then appropriate call or operator, ie:

>>> getattr(f, "attr1")["w"] = "w"
>>> getattr(f, "attr2").append(42)


FWIW, it's usually better to hide the mere fact that f.attr1 is a list and f.attr2 a dict. Here a "clean" solution would be to make attr1 and attr2 implementation attributes and provide an API over it, but it might be overkill.

HTH
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to