Instances of class object not modifiable?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Krzysztof Stachlewski

    #1

    Instances of class object not modifiable?

    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.[color=blue][color=green][color=darkred]
    >>> o = object()
    >>> o.a = 5[/color][/color][/color]
    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    AttributeError: 'object' object has no attribute 'a'

    But if I do:[color=blue][color=green][color=darkred]
    >>> class c(object):
    >>> pass
    >>> o = c()
    >>> o.a = 5[/color][/color][/color]

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

    --
    Stach Tlen: stachobywatelpl , GG: 1811474
    Jabber: stach at jabber atman pl
  • Steven Bethard

    #2
    Re: Instances of class object not modifiable?

    Krzysztof Stachlewski wrote:[color=blue]
    > 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.
    >[color=green][color=darkred]
    >>>>o = object()
    >>>>o.a = 5[/color][/color]
    >
    > Traceback (most recent call last):
    > File "<stdin>", line 1, in ?
    > AttributeError: 'object' object has no attribute 'a'
    >
    > But if I do:
    >[color=green][color=darkred]
    >>>>class c(object):
    >>>> pass
    >>>>o = c()
    >>>>o.a = 5[/color][/color]
    >
    >
    > ...then it, of course, works.
    > So what's wrong with the first example?[/color]

    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 "<interacti ve 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&at id=305470&aid=1 094542&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 <steven.bethard @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::
    [color=blue][color=green][color=darkred]
    >>> def f(x):[/color][/color][/color]
    ... return Bunch(double=2* x, squared=x**2)
    ...[color=blue][color=green][color=darkred]
    >>> y = f(10)
    >>> y.double[/color][/color][/color]
    20[color=blue][color=green][color=darkred]
    >>> y.squared[/color][/color][/color]
    100


    Representing Hierarchical Data
    ------------------------------

    The type suggested in this PEP also allows a simple means of
    representing hierarchical data that allows attribute-style access::
    [color=blue][color=green][color=darkred]
    >>> x = Bunch(spam=Bunc h(rabbit=1, badger=[2, 3, 4]), ham='neewom')
    >>> x.spam.badger[/color][/color][/color]
    [2, 3, 4][color=blue][color=green][color=darkred]
    >>> x.ham[/color][/color][/color]
    '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::
    [color=blue][color=green][color=darkred]
    >>> Bunch(eggs=1, spam=2, ham=3)[/color][/color][/color]
    Bunch(eggs=1, ham=3, spam=2)[color=blue][color=green][color=darkred]
    >>> Bunch({'eggs':1 , 'spam':2, 'ham':3})[/color][/color][/color]
    Bunch(eggs=1, ham=3, spam=2)[color=blue][color=green][color=darkred]
    >>> Bunch([('eggs',1), ('spam',2), ('ham',3)])[/color][/color][/color]
    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::
    [color=blue][color=green][color=darkred]
    >>> x = Bunch(parrot=Bu nch(lumberjack= True, spam=42), peng='shrub')
    >>> y = Bunch(peng='shr ub', parrot=Bunch(sp am=42, lumberjack=True ))
    >>> z = Bunch(parrot=Bu nch(lumberjack= True), peng='shrub')
    >>> x == y[/color][/color][/color]
    True[color=blue][color=green][color=darkred]
    >>> x == z[/color][/color][/color]
    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::
    [color=blue][color=green][color=darkred]
    >>> import xml.dom.minidom
    >>> def getbunch(elemen t):[/color][/color][/color]
    ... result = Bunch()
    ... if element.attribu tes:
    ... result.update(e lement.attribut es.items())
    ... children = {}
    ... for child in element.childNo des:
    ... if child.nodeType == xml.dom.minidom .Node.TEXT_NODE :
    ... children.setdef ault('text', []).append(
    ... child.nodeValue )
    ... else:
    ... children.setdef ault(child.node Name, []).append(
    ... getbunch(child) )
    ... result.update(c hildren)
    ... return result
    ...[color=blue][color=green][color=darkred]
    >>> doc = xml.dom.minidom .parseString("" "\[/color][/color][/color]
    ... <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>""")[color=blue][color=green][color=darkred]
    >>> b = getbunch(doc.do cumentElement)
    >>> b.a[0].b[1][/color][/color][/color]
    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:

    Comment

    • Nick Coghlan

      #3
      Re: Instances of class object not modifiable?

      Steven Bethard wrote:[color=blue]
      > Open Issues
      > ===========
      > What should the type be named? Some suggestions include 'Bunch',
      > 'Record' and 'Struct'.[/color]

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

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

      --
      Nick Coghlan | ncoghlan@email. com | Brisbane, Australia
      ---------------------------------------------------------------

      Comment

      Working...