views:

362

answers:

6

In Javascript it would be:

var newObject = { 'propertyName' : 'propertyValue' };

How to do it in Python?

+7  A: 

I don't know if there's a built-in way to do it, but you can always define a class like this:

class InlineClass(object):
    def __init__(self, dict):
 self.__dict__ = dict

obj = InlineClass({'propertyName' : 'propertyValue'})
Smashery
Interesting! (stupid min char comment limit)
Jader Dias
+2  A: 

I like Smashery's idea, but Python seems content to let you modify classes on your own:

>>> class Inline(object):
...     pass
...
>>> obj = Inline()
>>> obj.test = 1
>>> obj.test
1
>>>

Works just fine in Python 2.5 for me. Note that you do have to do this to a class derived from object - it won't work if you change the line to obj = object.

Chris Lutz
Yep, you can do that - but for some strange reason, you just can't use object() - you have to create your own class.
Smashery
if you want an inline class, you can use `obj = lambda: None`, which is bizarre, but will perform the necessary tasks...
Peter
@Peter - I didn't know that. However, now that I see it, I like SilentGhost's answer much better.
Chris Lutz
I removed the constructor to show the shortest way to achieve it
Jader Dias
@Jader - Fair enough. It looks better without it.
Chris Lutz
@Smashery: the "strange reason" is that type `object` is the root of the object inheritance tree, and if it had an associated dict to hold properties, all objects in Python would have to have an associated dict. I do actually wish there was a standard type that just made an empty container class, but it's pretty darn easy to just declare your own.
steveha
+11  A: 
obj = type('obj', (object,), {'propertyName' : 'propertyValue'})

there are two kinds of type function uses.

SilentGhost
+1 for the best answer by far.
Chris Lutz
+1 - Very interesting! I wasn't familiar with that use of the type function - could you please link me to some documentation on that?
Smashery
http://docs.python.org/library/functions.html#type
Chris Lutz
oopsm Chris was faster, but I've added link to answer anyway
SilentGhost
Well it's clever, but needlessly so, and obfuscatory. -1
Jonathan Feinberg
how is this obfuscatory? it's a proper documented behaviour.
SilentGhost
Interesting, the best answer so far. It seems that it won't get any better.
Jader Dias
Documented but obscure behavior. I'm pretty sure 99.9% of Python programmers' initial reaction to seeing this in real code would be "WTF!?".
Laurence Gonsalves
Actually, @Laurence, my reaction was, "Woah, I bet that creates a new instance of a made up `'obj'` class that inherits from the `object` with a `'propertyName'` member set to `'propertyValue'` ." And what do you know? I was right! I don't think it's too unintuitive.
Chris Lutz
It is flexible, terse and yet readable code like this that makes me choose python.
Tom Leys
+1 true one liner
Kamil Szot
Chris: You admit that you didn't know what the code did. You were only able to guess correctly given the fact that you knew it was supposed to do what the question was asking for. You wouldn't have had that context in real code.
Laurence Gonsalves
For completeness, to create an actual *instance* of the type instead of just a type object, this needs a trailing `()`: `obj = type('obj', (object,), {'propertyName' : 'propertyValue'})()`
Greg Hewgill
@Laurence - I guessed because I didn't know what else it could reasonably do. Context may help, but this statement will probably never be used without context.
Chris Lutz
In my opinion, this is an example of code that "accidentally" does something, without in any way **meaning** what it's being used for, and definitely without addressing the design that the OP seems to be struggling with. That's why I downvoted it. I don't think solutions like that should be rewarded or imitated. I cheerfully accept and acknowledge that I'm in the minority!
Jonathan Feinberg
It's interesting that this "readable" code has been upvoted so much despite the bug that Greg Hewgill points out.
Laurence Gonsalves
@Laurence: there's no *bug*, it works perfectly fine w/o instantiation. I personally don't see why would you want to instantiate this object at all, but of course Python is not preventing you from doing so.
SilentGhost
+1  A: 

Peter's answer

obj = lambda: None
obj.propertyName = 'propertyValue'
Jader Dias
A: 
class test:
    def __setattr__(self,key,value):
        return value


myObj = test()
myObj.mykey = 'abc' # set your property and value
There is no need to define __setattr__, see Chris response
Jader Dias
A: 

It is easy in Python to declare a class with an __init__() function that can set up the instance for you, with optional arguments. If you don't specify the arguments you get a blank instance, and if you specify some or all of the arguments you initialize the instance.

I explained it here (my highest-rated answer to date) so I won't retype the explanation. But, if you have questions, ask and I'll answer.

If you just want a generic object whose class doesn't really matter, you can do this:

class Generic(object):
    pass

x = Generic()
x.foo = 1
x.bar = 2
x.baz = 3

An obvious extension would be to add an __str__() function that prints something useful.

This trick is nice sometimes when you want a more-convenient dictionary. I find it easier to type x.foo than x["foo"].

steveha