Re: converting dict to object

Discussion in 'Python' started by Gabriel Genellina, Dec 2, 2006.

  1. At Friday 1/12/2006 22:48, rieh25 wrote:

    >If I have a dictionary such as:
    >
    >d = {'a' : 1, 'b' : 2}
    >
    >is there a way to convert it into an object o, such as:
    >
    >o.a = 1
    >o.b = 2


    >>> class X(object):

    .... def __init__(self, d): self.__dict__.update(d)
    ....
    >>> d = {'a' : 1, 'b' : 2}
    >>> o=X(d)
    >>> o.a

    1
    >>> o.b

    2
    >>>



    --
    Gabriel Genellina
    Softlab SRL

    __________________________________________________
    Correo Yahoo!
    Espacio para todos tus mensajes, antivirus y antispam ¡gratis!
    ¡Abrí tu cuenta ya! - http://correo.yahoo.com.ar
     
    Gabriel Genellina, Dec 2, 2006
    #1
    1. Advertising

  2. Hi!

    Yes.

    But...

    Try: d = {'a': 1, 'b': 2, 'def': 123}

    Ok, I go out...

    --
    @-salutations

    Michel Claveau
     
    Michel Claveau, Dec 2, 2006
    #2
    1. Advertising

  3. Gabriel Genellina

    Neil Cerutti Guest

    On 2006-12-02, Michel Claveau <> wrote:
    > Hi!
    >
    > Yes.
    >
    > But...
    >
    > Try: d = {'a': 1, 'b': 2, 'def': 123}
    >
    > Ok, I go out...


    How to convert a list of strings into a list of integers:

    a = ['82', '4', '16']

    ai = [int(i) for i in a]

    Yes.

    But...

    Try: a = ['82', '4', '16', 'foo']

    Ok, I go out...

    --
    Neil Cerutti
     
    Neil Cerutti, Dec 2, 2006
    #3
  4. Gabriel Genellina

    John Machin Guest

    Neil Cerutti wrote:
    > On 2006-12-02, Michel Claveau <> wrote:
    > > Hi!
    > >
    > > Yes.
    > >
    > > But...
    > >
    > > Try: d = {'a': 1, 'b': 2, 'def': 123}
    > >
    > > Ok, I go out...

    >
    > How to convert a list of strings into a list of integers:
    >
    > a = ['82', '4', '16']
    >
    > ai = [int(i) for i in a]
    >
    > Yes.
    >
    > But...
    >
    > Try: a = ['82', '4', '16', 'foo']
    >
    > Ok, I go out...



    Michel was making (part of) a valid point: dictionaries have more
    flexibility in choice of keys than objects have in attribute names.
    More completely:

    Suppose d.keys() produces ["one", "def", "foo bar", 3, "3"]

    o.one is OK.

    o.def is not OK ["def" is a keyword] but getattr(o, "def") still works.

    o.foo bar is not OK ["foo bar" is not a valid identifier] but
    getattr(o, "foo bar") still works.

    o.3 is not OK ["3" is not a valid identifier] but getattr(o, "3") still
    works.

    getattr(o, 3) doesn't work [3 is not a string]; you would have to do
    o.__dict__[3] to access the value -- no advantage over keeping it in a
    dict.

    The OP might consider adding code to the __init__ method to check for
    cases where the dictionary key is not a string containing a valid
    Python identifier (not a keyword).

    Note: I have done a reasonable number of exercises that involved taking
    a database table definition or a flat file record definition or the
    headings in an XLS worksheet or CSV file and ending up with names for
    attributes of Python objects. Various heuristics are necessary of
    course to get valid identifers without duplicates, but I've never been
    bitten by the keyword problem. I'll have to confess that I wasn't aware
    of the problem until the 3rd reading of Michel's message :)

    Any experiences of keyword-bite?

    Observation: the keyword module's iskeyword() function gives an easy
    check. If one is supporting multiple versions of Python, a more
    complicated (overkill?) approach might be desirable: use the latest
    version of Python to generate a source file containing the latest
    keywords from keyword.kwlist.

    Cheers,
    John
     
    John Machin, Dec 2, 2006
    #4
  5. John Machin wrote:

    > Any experiences of keyword-bite?


    creating or manipulating CSS-styled (X)HTML using an XML binding that
    exposes XML attributes as Python attributes.

    (this could be viewed as an unnecessary restriction in the Python
    parser; it wouldn't be too hard to allow reserved words for keyword
    argument names and for attribute access; iirc, Jython already does this,
    and Paul Svensson posted a patch for CPython a couple of years ago.
    PEP-time, anyone?)

    </F>
     
    Fredrik Lundh, Dec 2, 2006
    #5
  6. On Sat, 02 Dec 2006 12:16:24 -0800, John Machin wrote:

    > The OP might consider adding code to the __init__ method to check for
    > cases where the dictionary key is not a string containing a valid
    > Python identifier (not a keyword).


    If the OP is doing something like this:

    attributes = {"length": 15, "id": 2345}
    # attribute names are known at compile time, created by the coder
    obj.__dict__.update(attributes)
    print obj.length
    print obj.id

    then checking that "length" and "id" are valid identifiers is hardly
    necessary, any more than this would be:

    class Spam:
    def __init__(self, length, id):
    check_valid_indentifier("length")
    self.length = length
    check_valid_indentifier("id")
    self.id = id


    But if he's doing something like this:

    attributes = fetch_user_dict()
    # attribute names aren't known until runtime
    obj.__dict__.update(attributes)
    for key in attributes:
    print getattr(obj, key)

    then it is also redundant to check for valid identifiers, since getattr()
    doesn't need them. However, one might still need to test for accidental
    clashes with pre-existing object attributes.

    On the third hand, if that's the case then there seems to be no real
    advantage to converting the dict into object attributes. Why not just
    delegate to a saved copy of the dict?

    class Spam:
    def __init__(self, d):
    self._d = d
    def __getitem__(self, key):
    return self._d[key]
    def __setitem__(self, key, value):
    self._d[key] = value

    s = Spam({"a": 1, "something else": 2})
    s["a"]
    s["something else"]




    --
    Steven.
     
    Steven D'Aprano, Dec 3, 2006
    #6
  7. Gabriel Genellina

    John Machin Guest

    Steven D'Aprano wrote:
    > On Sat, 02 Dec 2006 12:16:24 -0800, John Machin wrote:
    >
    > > The OP might consider adding code to the __init__ method to check for
    > > cases where the dictionary key is not a string containing a valid
    > > Python identifier (not a keyword).

    >

    [snip]
    > But if he's doing something like this:
    >
    > attributes = fetch_user_dict()
    > # attribute names aren't known until runtime
    > obj.__dict__.update(attributes)
    > for key in attributes:
    > print getattr(obj, key)
    >
    > then it is also redundant to check for valid identifiers, since getattr()
    > doesn't need them.


    but getattr() needs strings.
     
    John Machin, Dec 3, 2006
    #7
  8. On Sat, 02 Dec 2006 17:00:15 -0800, John Machin wrote:

    >
    > Steven D'Aprano wrote:
    >> On Sat, 02 Dec 2006 12:16:24 -0800, John Machin wrote:
    >>
    >> > The OP might consider adding code to the __init__ method to check for
    >> > cases where the dictionary key is not a string containing a valid
    >> > Python identifier (not a keyword).

    >>

    > [snip]
    >> But if he's doing something like this:
    >>
    >> attributes = fetch_user_dict()
    >> # attribute names aren't known until runtime
    >> obj.__dict__.update(attributes)
    >> for key in attributes:
    >> print getattr(obj, key)
    >>
    >> then it is also redundant to check for valid identifiers, since getattr()
    >> doesn't need them.

    >
    > but getattr() needs strings.


    Well, that's true, but if the dict is being read from a file or with
    raw_input, the keys will naturally be strings. But even if it is some
    arbitrary dict, the keys still don't need to be checked for valid
    identifiers, merely checked for strings. And again, keeping the
    keys/values in a dict instead of converting to object attributes naturally
    solves that problem -- or rather, it isn't a problem that needs to be
    solved.

    Either way, I see no advantage to taking an arbitrary dict and converting
    it into object attributes. It sounds to me like "when the only tool you
    have is Java, everything looks like an object attribute" coding :)

    I'd suggest that the "right" answer to the OP's original question "How
    do I convert a dict to object attributes?" is "Don't do that", regardless
    that it is technically possible.

    Maybe I'm wrong and there are lots of really handy uses for such a tactic.
    Can anyone suggest any?



    --
    Steven.
     
    Steven D'Aprano, Dec 3, 2006
    #8
  9. Gabriel Genellina

    Neil Cerutti Guest

    On 2006-12-02, John Machin <> wrote:
    > Neil Cerutti wrote:
    >> On 2006-12-02, Michel Claveau <> wrote:
    >> > Hi!
    >> >
    >> > Yes.
    >> >
    >> > But...
    >> >
    >> > Try: d = {'a': 1, 'b': 2, 'def': 123}
    >> >
    >> > Ok, I go out...

    >>
    >> How to convert a list of strings into a list of integers:
    >>
    >> a = ['82', '4', '16']
    >>
    >> ai = [int(i) for i in a]
    >>
    >> Yes.
    >>
    >> But...
    >>
    >> Try: a = ['82', '4', '16', 'foo']
    >>
    >> Ok, I go out...

    >
    > Michel was making (part of) a valid point: dictionaries have
    > more flexibility in choice of keys than objects have in
    > attribute names. More completely:
    >
    > Suppose d.keys() produces ["one", "def", "foo bar", 3, "3"]
    >
    > o.one is OK.


    I made the assumption that Michael was also the original poster,
    and had somehow laid a clever trap. If I was wrong about that, my
    apologies. It's one thing to ask how to convert 'a' and 'b' to
    attributes, but quite another to convert arbitrary text.

    > The OP might consider adding code to the __init__ method to
    > check for cases where the dictionary key is not a string
    > containing a valid Python identifier (not a keyword).


    That raises the interesting question of what to do in that case.
    Just letting an error occur might be perfectly good behavior.
    Plus, I didn't know about...

    > Observation: the keyword module's iskeyword() function gives an
    > easy check. If one is supporting multiple versions of Python, a
    > more complicated (overkill?) approach might be desirable: use
    > the latest version of Python to generate a source file
    > containing the latest keywords from keyword.kwlist.


    Thanks for the pointer to keyword module. I hadn't noticed it
    yet.

    --
    Neil Cerutti
     
    Neil Cerutti, Dec 3, 2006
    #9
  10. Gabriel Genellina

    John Machin Guest

    Neil Cerutti wrote:

    >
    > Thanks for the pointer to keyword module. I hadn't noticed it
    > yet.


    Bonus: you got an extremely fresh, scarcely used pointer -- I wasn't
    aware of it myself till today :)

    Cheers,
    John
     
    John Machin, Dec 3, 2006
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Skip Montanaro
    Replies:
    0
    Views:
    423
    Skip Montanaro
    Aug 15, 2003
  2. Alexander Kozlovsky

    dict!ident as equivalent of dict["ident"]

    Alexander Kozlovsky, May 21, 2006, in forum: Python
    Replies:
    5
    Views:
    367
    Alexander Kozlovsky
    May 22, 2006
  3. rieh25

    converting dict to object

    rieh25, Dec 2, 2006, in forum: Python
    Replies:
    1
    Views:
    280
    Carl D. Roth
    Dec 2, 2006
  4. Paul Melis

    dict.has_key(x) versus 'x in dict'

    Paul Melis, Dec 6, 2006, in forum: Python
    Replies:
    48
    Views:
    1,337
    Kent Johnson
    Dec 15, 2006
  5. Almad
    Replies:
    8
    Views:
    416
    Terry Reedy
    Dec 14, 2006
Loading...

Share This Page