89

In Javascript it would be:

var newObject = { 'propertyName' : 'propertyValue' };
newObject.propertyName;  // returns "propertyValue"

But the same syntax in Python would create a dictionary, and that's not what I want

new_object = {'propertyName': 'propertyValue'}
new_object.propertyName  # raises an AttributeError
2

9 Answers 9

131
obj = type('obj', (object,), {'propertyName' : 'propertyValue'})

there are two kinds of type function uses.

Sign up to request clarification or add additional context in comments.

16 Comments

Documented but obscure behavior. I'm pretty sure 99.9% of Python programmers' initial reaction to seeing this in real code would be "WTF!?".
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.
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'})()
It's interesting that this "readable" code has been upvoted so much despite the bug that Greg Hewgill points out.
In Python 3, you don't need to inherit from object, you can just do obj = type('obj', (), {'property_name' : 'property_value'})
|
80

Python 3.3 added the SimpleNamespace class for that exact purpose:

>>> from types import SimpleNamespace

>>> obj = SimpleNamespace(propertyName='propertyValue')
>>> obj
namespace(propertyName='propertyValue')

>>> obj.propertyName
'propertyValue'

In addition to the appropriate constructor to build the object, SimpleNamespace defines __repr__ and __eq__ (documented in 3.4) to behave as expected.

1 Comment

This should be the accepted answer. Far more readable than creating a new type and intuitive.
41

Peter's answer

obj = lambda: None
obj.propertyName = 'propertyValue'

2 Comments

@ManelClos he is creating a function object that returns none which you could see with obj(). The function object can have properties.
@jeremyjjbrown What are you trying to say?
15

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'})

Comments

8

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.

6 Comments

Yep, you can do that - but for some strange reason, you just can't use object() - you have to create your own class.
if you want an inline class, you can use obj = lambda: None, which is bizarre, but will perform the necessary tasks...
@Peter - I didn't know that. However, now that I see it, I like SilentGhost's answer much better.
I removed the constructor to show the shortest way to achieve it
@Jader - Fair enough. It looks better without it.
|
5

SilentGhost had a good answer, but his code actually creates a new object of metaclass type, in other words it creates a class. And classes are objects in Python!

obj = type('obj', (object,), {'propertyName' : 'propertyValue'})
type(obj) 

gives

<class 'type'>

To create a new object of a custom or build-in class with dict attributes (aka properties) in one line I'd suggest to just call it:

new_object = type('Foo', (object,), {'name': 'new object'})()

and now

type(new_object) 

is

<class '__main__.Foo'>

which means it's an object of class Foo

I hope it helps those who are new to Python.

Comments

4

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"].

Comments

3

Another viable option is to use namedtuple:

from collections import namedtuple

message = namedtuple('Message', ['propertyName'], verbose=True)
messages = [
    message('propertyValueOne'),
    message('propertyValueTwo')
]

Comments

-1
class test:
    def __setattr__(self,key,value):
        return value


myObj = test()
myObj.mykey = 'abc' # set your property and value

1 Comment

There is no need to define setattr, see Chris response

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.