how do i create such a thing?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Lowell Kirsh

    #1

    how do i create such a thing?

    I want to create a class called DefaultAttr which returns a default
    value for all attributes which haven't been given values yet. It will
    work like this:
    [color=blue][color=green]
    >> x = DefaultAttr(99)
    >> print x.foo[/color][/color]
    99[color=blue][color=green]
    >> print x.bar[/color][/color]
    99[color=blue][color=green]
    >> x.foo = 7
    >> print x.foo[/color][/color]
    7

    I already have a similar class called DefaultDict which works similarly
    which I assume would be a good thing to use.

    Lowell
  • Pedro Werneck

    #2
    Re: how do i create such a thing?

    Hi,

    If you need direct access to some atribute, use object.__getatt ribute__.

    [color=blue][color=green][color=darkred]
    >>> class DefaultAttr(obj ect):[/color][/color][/color]
    .... def __init__(self, default):
    .... self.default = default
    .... def __getattribute_ _(self, name):
    .... try:
    .... value = object.__getatt ribute__(self, name)
    .... except AttributeError:
    .... value = self.default
    .... return value
    ....[color=blue][color=green][color=darkred]
    >>> x = DefaultAttr(99)
    >>>
    >>> print x.a[/color][/color][/color]
    99[color=blue][color=green][color=darkred]
    >>> x.a = 10
    >>> print x.a[/color][/color][/color]
    10[color=blue][color=green][color=darkred]
    >>>[/color][/color][/color]



    On Sun, 30 Jan 2005 13:54:38 -0800
    Lowell Kirsh <lkirsh@cs.ubc. ca> wrote:
    [color=blue]
    > I want to create a class called DefaultAttr which returns a default
    > value for all attributes which haven't been given values yet. It will
    > work like this:
    >[color=green][color=darkred]
    > >> x = DefaultAttr(99)
    > >> print x.foo[/color][/color]
    > 99[color=green][color=darkred]
    > >> print x.bar[/color][/color]
    > 99[color=green][color=darkred]
    > >> x.foo = 7
    > >> print x.foo[/color][/color]
    > 7
    >
    > I already have a similar class called DefaultDict which works
    > similarly which I assume would be a good thing to use.
    >
    > Lowell
    > --
    > http://mail.python.org/mailman/listinfo/python-list[/color]

    Comment

    • Steven Bethard

      #3
      Re: how do i create such a thing?

      Pedro Werneck wrote:[color=blue]
      > If you need direct access to some atribute, use object.__getatt ribute__.
      >[color=green][color=darkred]
      >>>>class DefaultAttr(obj ect):[/color][/color]
      >
      > ... def __init__(self, default):
      > ... self.default = default
      > ... def __getattribute_ _(self, name):
      > ... try:
      > ... value = object.__getatt ribute__(self, name)
      > ... except AttributeError:
      > ... value = self.default
      > ... return value
      > ...
      >[color=green][color=darkred]
      >>>>x = DefaultAttr(99)
      >>>>print x.a[/color][/color]
      > 99
      >[color=green][color=darkred]
      >>>>x.a = 10
      >>>>print x.a[/color][/color]
      > 10[/color]

      Of if you only want to deal with the case where the attribute doesn't
      exist, you can use getattr, which gets called when the attribute can't
      be found anywhere else:

      py> class DefaultAttr(obj ect):
      .... def __init__(self, default):
      .... self.default = default
      .... def __getattr__(sel f, name):
      .... return self.default
      ....
      py> x = DefaultAttr(99)
      py> x.a
      99
      py> x.a = 10
      py> x.a
      10

      Steve

      Comment

      • Alex Martelli

        #4
        Re: how do i create such a thing?

        Steven Bethard <steven.bethard @gmail.com> wrote:
        [color=blue]
        > Of if you only want to deal with the case where the attribute doesn't
        > exist, you can use getattr, which gets called when the attribute can't
        > be found anywhere else:
        >
        > py> class DefaultAttr(obj ect):
        > ... def __init__(self, default):
        > ... self.default = default
        > ... def __getattr__(sel f, name):
        > ... return self.default
        > ...
        > py> x = DefaultAttr(99)
        > py> x.a
        > 99
        > py> x.a = 10
        > py> x.a
        > 10[/color]

        This is a good approach, but it's fragile regarding specialnames.
        [color=blue][color=green][color=darkred]
        >>> class DefaultAttr(obj ect):[/color][/color][/color]
        .... def __init__(self, default): self.default = default
        .... def __getattr__(sel f, name): return self.default
        ....[color=blue][color=green][color=darkred]
        >>> import copy
        >>> copy.copy(Defau ltAttr(99))[/color][/color][/color]
        Traceback (most recent call last):
        File "<stdin>", line 1, in ?
        File "/usr/local/lib/python2.4/copy.py", line 87, in copy
        rv = reductor(2)
        TypeError: 'int' object is not callable

        There are many more, worse example for classic classes, but even in
        newstyle classes you must consider that once in a while a system routine
        will try a getattr(someins t, '__aspecialname __', None) or the like --
        and your class is making its instances claim to have ANY special name
        that may be introspected for in this way. This can be a pernicious lie,
        since your class in fact has no idea whatsoever what that specialname
        and the corresponding value might be for.

        It's HIGHLY advisable to have your __getattr__ methods raise
        AttributeError for any requested name that starts and ends with double
        underscores, possibly with some specific and specifically designed
        exceptions.


        Alex

        Comment

        • Lowell Kirsh

          #5
          Re: how do i create such a thing?

          What might these exceptions be?
          [color=blue]
          > It's HIGHLY advisable to have your __getattr__ methods raise
          > AttributeError for any requested name that starts and ends with double
          > underscores, possibly with some specific and specifically designed
          > exceptions.
          >
          >
          > Alex[/color]

          Comment

          • Alex Martelli

            #6
            Re: how do i create such a thing?

            Lowell Kirsh <lkirsh@cs.ubc. ca> wrote:
            [color=blue]
            > What might these exceptions be?
            >[color=green]
            > > It's HIGHLY advisable to have your __getattr__ methods raise
            > > AttributeError for any requested name that starts and ends with double
            > > underscores, possibly with some specific and specifically designed
            > > exceptions.[/color][/color]

            For example, delegation of such requests to some other object:
            def __getattr__(sel f, name):
            return getattr(self._d elegate, name)

            In such cases you may decide you do not need to block __specials__,
            because you're OK with having self._delegate supply them or be
            responsible to raise AttributeError if necessary.


            Alex

            Comment

            • Lowell Kirsh

              #7
              Re: how do i create such a thing?

              I'm not sure I get it. What's the purpose of using a delegate rather
              than having the object itself supply the return value?

              Alex Martelli wrote:[color=blue]
              > Lowell Kirsh <lkirsh@cs.ubc. ca> wrote:
              >
              >[color=green]
              >>What might these exceptions be?
              >>
              >>[color=darkred]
              >>>It's HIGHLY advisable to have your __getattr__ methods raise
              >>>AttributeErr or for any requested name that starts and ends with double
              >>>underscore s, possibly with some specific and specifically designed
              >>>exceptions .[/color][/color]
              >
              >
              > For example, delegation of such requests to some other object:
              > def __getattr__(sel f, name):
              > return getattr(self._d elegate, name)
              >
              > In such cases you may decide you do not need to block __specials__,
              > because you're OK with having self._delegate supply them or be
              > responsible to raise AttributeError if necessary.
              >
              >
              > Alex[/color]

              Comment

              • Steve Holden

                #8
                Re: how do i create such a thing?

                Lowell Kirsh wrote:
                [color=blue]
                > I'm not sure I get it. What's the purpose of using a delegate rather
                > than having the object itself supply the return value?
                >
                > Alex Martelli wrote:
                >[color=green]
                >> Lowell Kirsh <lkirsh@cs.ubc. ca> wrote:
                >>
                >>[color=darkred]
                >>> What might these exceptions be?
                >>>
                >>>
                >>>> It's HIGHLY advisable to have your __getattr__ methods raise
                >>>> AttributeError for any requested name that starts and ends with double
                >>>> underscores, possibly with some specific and specifically designed
                >>>> exceptions.[/color]
                >>
                >>
                >>
                >> For example, delegation of such requests to some other object:
                >> def __getattr__(sel f, name):
                >> return getattr(self._d elegate, name)
                >>
                >> In such cases you may decide you do not need to block __specials__,
                >> because you're OK with having self._delegate supply them or be
                >> responsible to raise AttributeError if necessary.
                >>
                >>
                >> Alex[/color][/color]

                The point is that you can keep a reference to some object, and it's the
                next best thing to having subclassed the object's class but with closer
                control.

                regards
                Steve

                A: Top-posting
                Q: What puts things in the wrong order on newsgroup postings
                --
                Meet the Python developers and your c.l.py favorites March 23-25
                Come to PyCon DC 2005 http://www.python.org/pycon/2005/
                Steve Holden http://www.holdenweb.com/

                Comment

                Working...