86

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
1

9 Answers 9

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

there are two kinds of type function uses.

16
  • 21
    Documented but obscure behavior. I'm pretty sure 99.9% of Python programmers' initial reaction to seeing this in real code would be "WTF!?". Commented Oct 7, 2009 at 1:22
  • 19
    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
    Commented Oct 7, 2009 at 1:27
  • 29
    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'})() Commented Oct 7, 2009 at 1:41
  • 2
    It's interesting that this "readable" code has been upvoted so much despite the bug that Greg Hewgill points out. Commented Oct 7, 2009 at 2:41
  • 2
    In Python 3, you don't need to inherit from object, you can just do obj = type('obj', (), {'property_name' : 'property_value'})
    – user3064538
    Commented Apr 16, 2020 at 14:34
75

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
  • 3
    This should be the accepted answer. Far more readable than creating a new type and intuitive. Commented Sep 10, 2021 at 13:27
39

Peter's answer

obj = lambda: None
obj.propertyName = 'propertyValue'
2
  • @ManelClos he is creating a function object that returns none which you could see with obj(). The function object can have properties. Commented Sep 23, 2017 at 3:27
  • 1
    @jeremyjjbrown What are you trying to say?
    – Sam
    Commented May 17, 2021 at 14:07
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'})
0
7

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
  • 2
    Yep, you can do that - but for some strange reason, you just can't use object() - you have to create your own class.
    – Smashery
    Commented Oct 7, 2009 at 1:02
  • 6
    if you want an inline class, you can use obj = lambda: None, which is bizarre, but will perform the necessary tasks...
    – Peter
    Commented Oct 7, 2009 at 1:04
  • @Peter - I didn't know that. However, now that I see it, I like SilentGhost's answer much better.
    – Chris Lutz
    Commented Oct 7, 2009 at 1:08
  • I removed the constructor to show the shortest way to achieve it
    – Jader Dias
    Commented Oct 7, 2009 at 1:18
  • @Jader - Fair enough. It looks better without it.
    – Chris Lutz
    Commented Oct 7, 2009 at 1:21
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.

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

3

Another viable option is to use namedtuple:

from collections import namedtuple

message = namedtuple('Message', ['propertyName'], verbose=True)
messages = [
    message('propertyValueOne'),
    message('propertyValueTwo')
]
-1
class test:
    def __setattr__(self,key,value):
        return value


myObj = test()
myObj.mykey = 'abc' # set your property and value
1
  • There is no need to define setattr, see Chris response
    – Jader Dias
    Commented Oct 7, 2009 at 11:33

Not the answer you're looking for? Browse other questions tagged or ask your own question.