By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
428,853 Members | 2,246 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 428,853 IT Pros & Developers. It's quick & easy.

Instances of class object not modifiable?

P: n/a
I tried to run the following piece of code:

Python 2.3.4 (#53, May 25 2004, 21:17:02) [MSC v.1200 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
o = object()
o.a = 5 Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'object' object has no attribute 'a'

But if I do: class c(object):
pass
o = c()
o.a = 5


....then it, of course, works.
So what's wrong with the first example?

--
Stach Tlen: stachobywatelpl, GG: 1811474
Jabber: stach at jabber atman pl
Jul 18 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
Krzysztof Stachlewski wrote:
I tried to run the following piece of code:

Python 2.3.4 (#53, May 25 2004, 21:17:02) [MSC v.1200 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
o = object()
o.a = 5
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'object' object has no attribute 'a'

But if I do:
class c(object):
pass
o = c()
o.a = 5

...then it, of course, works.
So what's wrong with the first example?


It's an instance of class object. ;)

If my memory serves me right, instances of object have no __dict__.

py> o = object()
py> o.__dict__
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
AttributeError: 'object' object has no attribute '__dict__'

Yup, that looks right. As I understand it, the reason for this is so
that classes which *really* need to be memory efficient can define
__slots__ instead and save some overhead.
If you're interested in having a builtin object that can be used as
above, you should help me rally for my Bunch type PEP. They haven't
given me a PEP number for it yet, but a patch is available[1] and I've
included the current draft of the PEP below.

[1]http://sourceforge.net/tracker/?func=detail&atid=305470&aid=1094542&group_id=5470

Steve

----------------------------------------------------------------------
PEP: XXX
Title: Generic Object Data Type
Version: $Revision: 1.0 $
Last-Modified: $Date: 2004/11/29 16:00:00 $
Author: Steven Bethard <st************@gmail.com>
Status: Draft
Type: Standards Track
Content-Type: text/x-rst
Created: 29-Nov-2004
Python-Version: 2.5
Post-History: 29-Nov-2004
Abstract
========

This PEP proposes a standard library addition to support the simple
creation of 'generic' objects which can be given named attributes
without the need to declare a class. Such attribute-value mappings are
intended to complement the name-value mappings provided by Python's
builtin dict objects.
Motivation
==========

Python's dict objects provide a simple way of creating anonymous
name-value mappings. These mappings use the __getitem__ protocol to
access the value associated with a name, so that code generally appears
like::

mapping['name']

Occasionally, a programmer may decide that dotted-attribute style access
is more appropriate to the domain than __getitem__ style access, and
that their mapping should be accessed like::

mapping.name

Currently, if a Python programmer makes this design decision, they are
forced to declare a new class, and then build instances of this class.
When no methods are to be associated with the attribute-value mappings,
declaring a new class can be overkill. This PEP proposes adding a
simple type to the collections module of the standard library that can
be used to build such attribute-value mappings.

Providing such a type allows the Python programmer to determine which
type of mapping is most appropriate to their domain and apply this
choice with minimal effort. Some of the suggested uses include:
Returning Named Results
-----------------------

It is often appropriate for a function that returns multiple items to
give names to the different items returned. The type suggested in this
PEP provides a simple means of doing this that allows the returned
values to be accessed in the usual attribute-style access::
def f(x): ... return Bunch(double=2*x, squared=x**2)
... y = f(10)
y.double 20 y.squared 100
Representing Hierarchical Data
------------------------------

The type suggested in this PEP also allows a simple means of
representing hierarchical data that allows attribute-style access::
x = Bunch(spam=Bunch(rabbit=1, badger=[2, 3, 4]), ham='neewom')
x.spam.badger [2, 3, 4] x.ham 'neewom'
Rationale
=========

As Bunch objects are intended primarily to replace simple, data-only
classes, simple Bunch construction was a primary concern. As such,
the Bunch constructor supports creation from keyword arguments, dicts,
and sequences of (attribute, value) pairs::
Bunch(eggs=1, spam=2, ham=3) Bunch(eggs=1, ham=3, spam=2) Bunch({'eggs':1, 'spam':2, 'ham':3}) Bunch(eggs=1, ham=3, spam=2) Bunch([('eggs',1), ('spam',2), ('ham',3)]) Bunch(eggs=1, ham=3, spam=2)

To allow attribute-value mappings to be easily combined, the update
method of Bunch objects supports similar arguments.

If Bunch objects are used to represent hierarchical data, comparison of
such objects becomes a concern. For this reason, Bunch objects support
object equality::
x = Bunch(parrot=Bunch(lumberjack=True, spam=42), peng='shrub')
y = Bunch(peng='shrub', parrot=Bunch(spam=42, lumberjack=True))
z = Bunch(parrot=Bunch(lumberjack=True), peng='shrub')
x == y True x == z False
Note that support for the various mapping methods, e.g.
__(get|set|del)item__, __len__, __iter__, __contains__, items, keys,
values, etc. was intentionally omitted as these methods did not seem to
be necessary for the core uses of an attribute-value mapping. If such
methods are truly necessary for a given use case, this may suggest that
a dict object is a more appropriate type for that use.
Examples
=========

Converting an XML DOM tree into a tree of nested Bunch objects::
import xml.dom.minidom
def getbunch(element): ... result = Bunch()
... if element.attributes:
... result.update(element.attributes.items())
... children = {}
... for child in element.childNodes:
... if child.nodeType == xml.dom.minidom.Node.TEXT_NODE:
... children.setdefault('text', []).append(
... child.nodeValue)
... else:
... children.setdefault(child.nodeName, []).append(
... getbunch(child))
... result.update(children)
... return result
... doc = xml.dom.minidom.parseString("""\ ... <xml>
... <a attr_a="1">
... a text 1
... <b attr_b="2" />
... <b attr_b="3"> b text </b>
... a text 2
... </a>
... <c attr_c="4"> c text </c>
... </xml>""") b = getbunch(doc.documentElement)
b.a[0].b[1]

Bunch(attr_b=u'3', text=[u' b text '])
Reference Implementation
========================

The code is available as SourceForge patch 1094542 [1]_.
Open Issues
===========
What should the type be named? Some suggestions include 'Bunch',
'Record' and 'Struct'.

Where should the type be placed? The current suggestion is the
collections module.
References
==========

... [1]
http://sourceforge.net/tracker/index...70&atid=305470


...
Local Variables:
mode: indented-text
indent-tabs-mode: nil
sentence-end-double-space: t
fill-column: 70
End:
Jul 18 '05 #2

P: n/a
Steven Bethard wrote:
Open Issues
===========
What should the type be named? Some suggestions include 'Bunch',
'Record' and 'Struct'.


Add 'namespace' to the list of name suggestions :)

Cheers,
Nick.
The name came up in some thread a few weeks back. . .

--
Nick Coghlan | nc******@email.com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net
Jul 18 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.