Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #7463 > unrolled thread

__dict__ is neato torpedo!

Started byAndrew Berg <bahamutzero8825@gmail.com>
First post2011-06-11 20:32 -0500
Last post2011-06-12 17:20 +0200
Articles 5 — 3 participants

Back to article view | Back to comp.lang.python


Contents

  __dict__ is neato torpedo! Andrew Berg <bahamutzero8825@gmail.com> - 2011-06-11 20:32 -0500
    Re: __dict__ is neato torpedo! Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-06-12 02:13 +0000
      Re: __dict__ is neato torpedo! Andrew Berg <bahamutzero8825@gmail.com> - 2011-06-11 21:28 -0500
        Re: __dict__ is neato torpedo! Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-06-12 08:47 +0000
          Re: __dict__ is neato torpedo! Hans Mulder <hansmu@xs4all.nl> - 2011-06-12 17:20 +0200

#7463 — __dict__ is neato torpedo!

FromAndrew Berg <bahamutzero8825@gmail.com>
Date2011-06-11 20:32 -0500
Subject__dict__ is neato torpedo!
Message-ID<mailman.140.1307842367.11593.python-list@python.org>
I'm pretty happy that I can copy variables and their value from one
object's namespace to another object's namespace with the same variable
names automatically:

class simpleObject():
    pass

a = simpleObject()
b = simpleObject()

a.val1 = 1
a.val2 = 2
b.__dict__.update(a.__dict__)
a.val1 = 'a'

>>> a.val1
'a'
>>> a.val2
2
>>> b.val1
1
>>> b.val2
2

The reason I'm posting this is to ask what to watch out for when doing
this. I've seen vague warnings that I don't really understand, and I'm
hoping someone can enlighten me.

[toc] | [next] | [standalone]


#7465

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2011-06-12 02:13 +0000
Message-ID<4df420b6$0$30002$c3e8da3$5496439d@news.astraweb.com>
In reply to#7463
On Sat, 11 Jun 2011 20:32:37 -0500, Andrew Berg wrote:

> I'm pretty happy that I can copy variables and their value from one
> object's namespace to another object's namespace with the same variable
> names automatically:
> 
> class simpleObject():
>     pass
> 
> a = simpleObject()
> b = simpleObject()
> 
> a.val1 = 1
> a.val2 = 2
> b.__dict__.update(a.__dict__)
[...]


> The reason I'm posting this is to ask what to watch out for when doing
> this. I've seen vague warnings that I don't really understand, and I'm
> hoping someone can enlighten me.

You are injecting data and code from one object to another. If you don't 
know what you're injecting, bad things could happen. Just like in real 
life :)

The update method unconditionally replaces any item in the first object 
that matches an item in the second. If it has things you don't want, too 
bad, you'll get them:


>>> class K(object):
...     data = "things"
...     status = "working hard for a living"
...
>>> a = K()
>>> b = K()
>>> b.data = "stuff and things"  # what you want
>>> b.status = "leaching off dear old granny"  # but not this one
>>>
>>> a.__dict__.update(b.__dict__)
>>> print(a.status)
leaching off dear old granny


So never update from a random object you don't know well.

A second, more subtle risk: not all objects have a __dict__. But if you 
obey the rule about never updating from arbitrary objects you don't know, 
then you won't be surprised by an object with no __dict__.

Other than that, using update is a good trick to have in your toolbox.




-- 
Steven

[toc] | [prev] | [next] | [standalone]


#7467

FromAndrew Berg <bahamutzero8825@gmail.com>
Date2011-06-11 21:28 -0500
Message-ID<mailman.143.1307845734.11593.python-list@python.org>
In reply to#7465
On 2011.06.11 09:13 PM, Steven D'Aprano wrote:
> So never update from a random object you don't know well.
Of course. In the project I'm working on, this will be used in the
__init__() method of a class that accepts a pair of dictionaries or
possibly **kwargs (for flexibility and to avoid the very problem of an
object without a __dict__).
> A second, more subtle risk: not all objects have a __dict__. But if you 
> obey the rule about never updating from arbitrary objects you don't know, 
> then you won't be surprised by an object with no __dict__.
What objects don't (other than the obvious ones like strings,
dictionaries, ints and lists)?

[toc] | [prev] | [next] | [standalone]


#7476

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2011-06-12 08:47 +0000
Message-ID<4df47d05$0$30002$c3e8da3$5496439d@news.astraweb.com>
In reply to#7467
On Sat, 11 Jun 2011 21:28:40 -0500, Andrew Berg wrote:

> On 2011.06.11 09:13 PM, Steven D'Aprano wrote:

>> A second, more subtle risk: not all objects have a __dict__. But if you
>> obey the rule about never updating from arbitrary objects you don't
>> know, then you won't be surprised by an object with no __dict__.
>
> What objects don't (other than the obvious ones like strings,
> dictionaries, ints and lists)?

namedtuple is another common example. 

In pure Python, objects created using __slots__ usually don't have a 
__dict__. Quite possibly C extension objects. There may be others.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#7484

FromHans Mulder <hansmu@xs4all.nl>
Date2011-06-12 17:20 +0200
Message-ID<4df4d94b$0$49042$e4fe514c@news.xs4all.nl>
In reply to#7476
On 12/06/11 10:47:01, Steven D'Aprano wrote:
> On Sat, 11 Jun 2011 21:28:40 -0500, Andrew Berg wrote:
>
>> On 2011.06.11 09:13 PM, Steven D'Aprano wrote:
>
>>> A second, more subtle risk: not all objects have a __dict__. But if you
>>> obey the rule about never updating from arbitrary objects you don't
>>> know, then you won't be surprised by an object with no __dict__.
>>
>> What objects don't (other than the obvious ones like strings,
>> dictionaries, ints and lists)?
>
> namedtuple is another common example.
>
> In pure Python, objects created using __slots__ usually don't have a
> __dict__. Quite possibly C extension objects. There may be others.

The base class 'object' is a well-known example:

 >>> ham = object()
 >>> ham.spam = 'eggs'
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'spam'
 >>>

But subclasses of object do have a __dict__ by default,
which is why you'd normally do:

 >>> class Ham(object):
...     pass
...
 >>> ham = Ham()
 >>> ham.spam = 'eggs'
 >>>

Here, the only reason for creating a subclass with no visible new
methods or attributes, is the unmentioned __dict__ attribute that
Ham instances have and 'object' instances lack.

-- HansM

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web