Getting a dictionary from an object

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Thanos Tsouanas

    Getting a dictionary from an object

    Hello.

    I would like to have a quick way to create dicts from object, so that a
    call to foo['bar'] would return obj.bar.

    The following works, but I would prefer to use a built-in way if one
    exists. Is there one?

    Thanks in advance.

    class dictobj(dict):
    """
    class dictobj(dict):
    A dictionary d with an object attached to it,
    which treats d['foo'] as d.obj.foo.
    """
    def __init__(self, obj):
    self.obj = obj
    def __getitem__(sel f, key):
    return self.obj.__geta ttribute__(key)

    --
    Thanos Tsouanas .: My Music: http://www.thanostsouanas.com/
    http://thanos.sians.org/ .: Sians Music: http://www.sians.org/
  • Bruno Desthuilliers

    #2
    Re: Getting a dictionary from an object

    Thanos Tsouanas a écrit :[color=blue]
    > Hello.
    >
    > I would like to have a quick way to create dicts from object, so that a
    > call to foo['bar'] would return obj.bar.
    >
    > The following works, but I would prefer to use a built-in way if one
    > exists. Is there one?
    >
    > Thanks in advance.
    >
    > class dictobj(dict):
    > """
    > class dictobj(dict):
    > A dictionary d with an object attached to it,
    > which treats d['foo'] as d.obj.foo.
    > """
    > def __init__(self, obj):
    > self.obj = obj
    > def __getitem__(sel f, key):
    > return self.obj.__geta ttribute__(key)[/color]

    I'd replace this last line with:
    return getattr(self.ob j, key)


    Now given your specs, I don't see what's wrong with your solution.

    Comment

    • Thanos Tsouanas

      #3
      Re: Getting a dictionary from an object

      On Sat, Jul 23, 2005 at 11:30:19AM +0200, Bruno Desthuilliers wrote:[color=blue]
      > Thanos Tsouanas a écrit :[color=green]
      > > class dictobj(dict):
      > > """
      > > class dictobj(dict):
      > > A dictionary d with an object attached to it,
      > > which treats d['foo'] as d.obj.foo.
      > > """
      > > def __init__(self, obj):
      > > self.obj = obj
      > > def __getitem__(sel f, key):
      > > return self.obj.__geta ttribute__(key)[/color]
      >
      > I'd replace this last line with:
      > return getattr(self.ob j, key)
      >
      > Now given your specs, I don't see what's wrong with your solution.[/color]

      I just dont want to use my class, if one already exists in the
      libraries (or any other way to achieve the same thing), that's all ;)

      Thanks for the tip.

      --
      Thanos Tsouanas .: My Music: http://www.thanostsouanas.com/
      http://thanos.sians.org/ .: Sians Music: http://www.sians.org/

      Comment

      • Steven D'Aprano

        #4
        Re: Getting a dictionary from an object

        On Sat, 23 Jul 2005 11:48:27 +0300, Thanos Tsouanas wrote:
        [color=blue]
        > Hello.
        >
        > I would like to have a quick way to create dicts from object, so that a
        > call to foo['bar'] would return obj.bar.[/color]

        That looks rather confusing to me. Why not just call obj.bar, since it
        doesn't look like you are actually using the dictionary at all?
        [color=blue]
        > The following works, but I would prefer to use a built-in way if one
        > exists. Is there one?
        >
        > Thanks in advance.
        >
        > class dictobj(dict):
        > """
        > class dictobj(dict):
        > A dictionary d with an object attached to it,
        > which treats d['foo'] as d.obj.foo.
        > """
        > def __init__(self, obj):
        > self.obj = obj
        > def __getitem__(sel f, key):
        > return self.obj.__geta ttribute__(key)[/color]

        I don't think this is particularly useful behaviour. How do you use it?

        py> D = dictobj("hello world")
        py> D
        {}
        py> D.obj
        'hello world'
        py> D["food"] = "spam"
        py> D
        {'food': 'spam'}
        py> D["food"]
        Traceback (most recent call last):
        File "<stdin>", line 1, in ?
        File "<stdin>", line 5, in __getitem__
        AttributeError: 'str' object has no attribute 'food'


        --
        Steven.


        Comment

        • Mike Meyer

          #5
          Re: Getting a dictionary from an object

          Steven D'Aprano <steve@REMOVETH IScyber.com.au> writes:[color=blue]
          > On Sat, 23 Jul 2005 11:48:27 +0300, Thanos Tsouanas wrote:[color=green]
          >> Hello.
          >>
          >> I would like to have a quick way to create dicts from object, so that a
          >> call to foo['bar'] would return obj.bar.[/color]
          >
          > That looks rather confusing to me. Why not just call obj.bar, since it
          > doesn't look like you are actually using the dictionary at all?[/color]

          Well, I needed exactly this functionality last week. I have a
          collection of (rather messy) classes that have a slew of attributes as
          values. I would have used a dictionary for this, but I didn't write
          the code.

          I have to be able to display these objects (in HTML, if it matters),
          and have as a requirement that the format string live in a database.

          My solution didn't look to different from dictobj. There's some extra
          mechanism to fetch the format string from the database, and some
          formatting of the attribute based on meta-information in the object,
          but it's the same basic idea.
          [color=blue][color=green]
          >> class dictobj(dict):
          >> """
          >> class dictobj(dict):
          >> A dictionary d with an object attached to it,
          >> which treats d['foo'] as d.obj.foo.
          >> """
          >> def __init__(self, obj):
          >> self.obj = obj
          >> def __getitem__(sel f, key):
          >> return self.obj.__geta ttribute__(key)[/color]
          >
          > I don't think this is particularly useful behaviour. How do you use it?[/color]

          def __str__(self):
          return self._format % self


          <mike
          --
          Mike Meyer <mwm@mired.or g> http://www.mired.org/home/mwm/
          Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.

          Comment

          • Thanos Tsouanas

            #6
            Re: Getting a dictionary from an object

            On Sat, Jul 23, 2005 at 11:22:21PM +1000, Steven D'Aprano wrote:[color=blue]
            > On Sat, 23 Jul 2005 11:48:27 +0300, Thanos Tsouanas wrote:[color=green]
            > > Hello.
            > >
            > > I would like to have a quick way to create dicts from object, so that a
            > > call to foo['bar'] would return obj.bar.[/color]
            >
            > That looks rather confusing to me. Why not just call obj.bar, since it
            > doesn't look like you are actually using the dictionary at all?
            >[color=green]
            > > [...][/color]
            >
            > I don't think this is particularly useful behaviour. How do you use it?[/color]

            print foo %do

            where do is a dictobj object...

            --
            Thanos Tsouanas .: My Music: http://www.thanostsouanas.com/
            http://thanos.sians.org/ .: Sians Music: http://www.sians.org/

            Comment

            • Steven Bethard

              #7
              Re: Getting a dictionary from an object

              Thanos Tsouanas wrote:[color=blue]
              > I would like to have a quick way to create dicts from object, so that a
              > call to foo['bar'] would return obj.bar.
              >
              > The following works, but I would prefer to use a built-in way if one
              > exists. Is there one?[/color]

              Maybe I'm not understanding your problem, but have you looked at the
              builtin "vars()"?

              STeVe

              Comment

              • Steven D'Aprano

                #8
                Re: Getting a dictionary from an object

                On Sat, 23 Jul 2005 13:50:36 -0400, Mike Meyer wrote:
                [color=blue][color=green]
                >> I don't think this is particularly useful behaviour. How do you use it?[/color]
                >
                > def __str__(self):
                > return self._format % self[/color]

                That doesn't work. It calls self.__str__ recursively until Python halts
                the process.
                [color=blue][color=green][color=darkred]
                >>> class Thing(dict):[/color][/color][/color]
                .... _format = "Thing %s is good."
                .... def __str__(self):
                .... return self._format % self
                ....[color=blue][color=green][color=darkred]
                >>> X = Thing()
                >>> X # calls __repr__ so is safe[/color][/color][/color]
                {}[color=blue][color=green][color=darkred]
                >>> str(X) # not safe[/color][/color][/color]
                File "<stdin>", line 4, in __str__
                File "<stdin>", line 4, in __str__
                ...
                File "<stdin>", line 4, in __str__
                File "<stdin>", line 4, in __str__
                RuntimeError: maximum recursion depth exceeded


                --
                Steven.

                Comment

                • Steven D'Aprano

                  #9
                  Re: Getting a dictionary from an object

                  On Sun, 24 Jul 2005 02:09:54 +0300, Thanos Tsouanas wrote:
                  [color=blue]
                  > On Sat, Jul 23, 2005 at 11:22:21PM +1000, Steven D'Aprano wrote:[color=green]
                  >> On Sat, 23 Jul 2005 11:48:27 +0300, Thanos Tsouanas wrote:[color=darkred]
                  >> > Hello.
                  >> >
                  >> > I would like to have a quick way to create dicts from object, so that a
                  >> > call to foo['bar'] would return obj.bar.[/color]
                  >>
                  >> That looks rather confusing to me. Why not just call obj.bar, since it
                  >> doesn't look like you are actually using the dictionary at all?
                  >>[color=darkred]
                  >> > [...][/color]
                  >>
                  >> I don't think this is particularly useful behaviour. How do you use it?[/color]
                  >
                  > print foo %do
                  >
                  > where do is a dictobj object...[/color]

                  Are you telling me that the ONLY thing you use dictobj objects for is to
                  print them?

                  I don't think so. I do know how to print an object, amazingly.

                  Perhaps you would like to explain how you use the rest of the
                  functionality of the dictobj, instead of taking my words out of context
                  and giving an inane answer.

                  Why jump through all those hoops to get attributes when Python already
                  provides indexing and attribute grabbing machinery that work well? Why do
                  you bother to subclass dict, only to mangle the dict __getitem__ method so
                  that you can no longer retrieve items from the dict?


                  --
                  Steven.

                  Comment

                  • Thanos Tsouanas

                    #10
                    Re: Getting a dictionary from an object

                    On Sun, Jul 24, 2005 at 01:43:43PM +1000, Steven D'Aprano wrote:[color=blue]
                    > On Sun, 24 Jul 2005 02:09:54 +0300, Thanos Tsouanas wrote:[color=green]
                    > >
                    > > print foo %do
                    > >
                    > > where do is a dictobj object...[/color]
                    >
                    > Are you telling me that the ONLY thing you use dictobj objects for is to
                    > print them?[/color]

                    I'm sorry to disappoint you, but yes. When you have a long text
                    template to fill-out, with lots of %(foo)s, and all those foos are
                    attributes of an object, it really helps to have dictobj.
                    [color=blue]
                    > I don't think so. I do know how to print an object, amazingly.[/color]

                    Please, tell me, how would you print it in my case?
                    [color=blue]
                    > Perhaps you would like to explain how you use the rest of the
                    > functionality of the dictobj, instead of taking my words out of context
                    > and giving an inane answer.[/color]

                    I dont see _ANY_ other functionality in the dictobj class. Do you?
                    [color=blue]
                    > Why jump through all those hoops to get attributes when Python already
                    > provides indexing and attribute grabbing machinery that work well? Why do
                    > you bother to subclass dict, only to mangle the dict __getitem__ method so
                    > that you can no longer retrieve items from the dict?[/color]

                    Because *obviously* I don't know of these indexing and attribute
                    grabbing machineries you are talking about in my case. If you cared to
                    read my first post, all I asked was for the "normal", "built-in" way to
                    do it. Now, is there one, or not?

                    --
                    Thanos Tsouanas .: My Music: http://www.thanostsouanas.com/
                    http://thanos.sians.org/ .: Sians Music: http://www.sians.org/

                    Comment

                    • Thanos Tsouanas

                      #11
                      Re: Getting a dictionary from an object

                      On Sat, Jul 23, 2005 at 06:59:43PM -0600, Steven Bethard wrote:[color=blue]
                      > Thanos Tsouanas wrote:[color=green]
                      > > I would like to have a quick way to create dicts from object, so that a
                      > > call to foo['bar'] would return obj.bar.
                      > >
                      > > The following works, but I would prefer to use a built-in way if one
                      > > exists. Is there one?[/color]
                      >
                      > Maybe I'm not understanding your problem, but have you looked at the
                      > builtin "vars()"?[/color]

                      I didn't know about it, but I knew about object.__dict__ which is, as I
                      see equivalent with vars(object). But it doesn't do the job for me,
                      since it fails to grab all obj.foo's, some of them being properties,
                      etc.

                      vars() is good to know though, Thanks!

                      --
                      Thanos Tsouanas .: My Music: http://www.thanostsouanas.com/
                      http://thanos.sians.org/ .: Sians Music: http://www.sians.org/

                      Comment

                      • Bruno Desthuilliers

                        #12
                        Re: Getting a dictionary from an object

                        Thanos Tsouanas a écrit :[color=blue]
                        > On Sun, Jul 24, 2005 at 01:43:43PM +1000, Steven D'Aprano wrote:[/color]

                        (snip)[color=blue]
                        >[color=green]
                        >>Why jump through all those hoops to get attributes when Python already
                        >>provides indexing and attribute grabbing machinery that work well? Why do
                        >>you bother to subclass dict, only to mangle the dict __getitem__ method so
                        >>that you can no longer retrieve items from the dict?[/color][/color]
                        [color=blue]
                        >
                        > Because *obviously* I don't know of these indexing and attribute
                        > grabbing machineries you are talking about in my case. If you cared to
                        > read my first post, all I asked was for the "normal", "built-in" way to
                        > do it. Now, is there one, or not?[/color]

                        If you re-read your first post, you'll notice that you didn't say
                        anything about the intention, only about implementation !-)

                        Now if your *only* need is to access object as a dict for formated
                        output, you don't need to subclass dict. This is (well, should be) enough:

                        class Wrapper(object) :
                        def __init__(self, obj):
                        self._obj = obj
                        def __getitem__(sel f, name):
                        return getattr(self._o bj, name)

                        This works with 'normal' attributes as well as with properties. Notice
                        that this wrapper is read-only, and don't pretend to be a real
                        dictionnary - but still it implements the minimum required interface for
                        "%(attname) s" like formatting.

                        HTH
                        Bruno

                        Comment

                        • Thanos Tsouanas

                          #13
                          Re: Getting a dictionary from an object

                          On Sun, Jul 24, 2005 at 02:01:30PM +0200, Bruno Desthuilliers wrote:[color=blue]
                          > Thanos Tsouanas a écrit :[color=green]
                          > > On Sun, Jul 24, 2005 at 01:43:43PM +1000, Steven D'Aprano wrote:
                          > >
                          > > Because *obviously* I don't know of these indexing and attribute
                          > > grabbing machineries you are talking about in my case. If you cared to
                          > > read my first post, all I asked was for the "normal", "built-in" way to
                          > > do it. Now, is there one, or not?[/color]
                          >
                          > If you re-read your first post, you'll notice that you didn't say
                          > anything about the intention, only about implementation !-)[/color]

                          """The following works, but I would prefer to use a built-in way if one
                          exists. Is there one?"""
                          [color=blue]
                          > Now if your *only* need is to access object as a dict for formated
                          > output, you don't need to subclass dict. This is (well, should be) enough:
                          >
                          > class Wrapper(object) :
                          > def __init__(self, obj):
                          > self._obj = obj
                          > def __getitem__(sel f, name):
                          > return getattr(self._o bj, name)
                          >
                          > This works with 'normal' attributes as well as with properties. Notice
                          > that this wrapper is read-only, and don't pretend to be a real
                          > dictionnary - but still it implements the minimum required interface for
                          > "%(attname) s" like formatting.[/color]

                          Thanks!! You made clear what 'the extra functionality' was. Indeed
                          there is no need to subclass dict...
                          [color=blue]
                          > HTH[/color]

                          it does!
                          [color=blue]
                          > Bruno
                          > --
                          > http://mail.python.org/mailman/listinfo/python-list[/color]

                          --
                          Thanos Tsouanas .: My Music: http://www.thanostsouanas.com/
                          http://thanos.sians.org/ .: Sians Music: http://www.sians.org/

                          Comment

                          • Bruno Desthuilliers

                            #14
                            Re: Getting a dictionary from an object

                            Bruno Desthuilliers a écrit :
                            (snip)[color=blue]
                            > class Wrapper(object) :
                            > def __init__(self, obj):
                            > self._obj = obj
                            > def __getitem__(sel f, name):
                            > return getattr(self._o bj, name)[/color]

                            If you want the Wrapper to be more like a Decorator (ie still can use
                            the Wrapper object as if it was the wrapped object), you can add this:

                            def __getattr__(sel f, name):
                            return getattr(self._o bj, name)

                            def __setattr__(sel f, name, val):
                            if name == '_obj':
                            super(Wrapper, self).__setattr __(name, val)
                            else:
                            setattr(self._o bj, name, val)

                            The Python cookbook may have some receipes too for this kind of funny
                            things...

                            Comment

                            • Bruno Desthuilliers

                              #15
                              Re: Getting a dictionary from an object

                              Steven D'Aprano a écrit :[color=blue]
                              > On Sun, 24 Jul 2005 02:09:54 +0300, Thanos Tsouanas wrote:
                              >
                              >[/color]
                              (snip)[color=blue]
                              >
                              > Are you telling me that the ONLY thing you use dictobj objects for is to
                              > print them?
                              >
                              > I don't think so. I do know how to print an object, amazingly.
                              >
                              > Perhaps you would like to explain how you use the rest of the
                              > functionality of the dictobj, instead of taking my words out of context
                              > and giving an inane answer.
                              >
                              > Why jump through all those hoops to get attributes when Python already
                              > provides indexing and attribute grabbing machinery that work well? Why do
                              > you bother to subclass dict, only to mangle the dict __getitem__ method so
                              > that you can no longer retrieve items from the dict?
                              >[/color]

                              The idea of the OP is not to use the dictobj as a full fledged dict,
                              just to wrap the obj in something that is dict-like enough to be used
                              for "%(attname) s" formatting. I also assume that he doesn't want to
                              manually alter the code of each and every class to achieve this !-)

                              So we can certainly agree that subclassing dict here is overkill and a
                              bit misleading, but there are probably better ways to express this
                              feeling. Of course, it would have been simpler if the OP had tell us
                              from the start what was it's use case, but what...

                              One could of course use metaclass tricks and the like to customize the
                              objects __str__ or __repr__ (as in David Mertz's gnosis.magic package),
                              but that would be overkill too IMHO.

                              The plain old Decorator[1] pattern is probably enough in this case,
                              since it's quite easy to implement a generic Decorator in Python.
                              Another solution could be to dynamically modify the to-be-wrapped
                              object's class to add a __getitem__ method.





                              Comment

                              Working...