Add property to object python

I want to create a dynamic object (inside another object) in Python and then add attributes to it.

I tried:

obj = someobject
obj.a = object()
setattr(obj.a, 'somefield', 'somevalue')

but this didn't work.

Any ideas?

edit:

I am setting the attributes from a for loop which loops through a list of values, e.g.

params = ['attr1', 'attr2', 'attr3']
obj = someobject
obj.a = object()

for p in params:
   obj.a.p # where p comes from for loop variable

In the above example I would get obj.a.attr1, obj.a.attr2, obj.a.attr3.

I used the setattr function because I didn't know how to do obj.a.NAME from a for loop.

How would I set the attribute based on the value of p in the example above?


For details on why it doesn't work, see Can't set attributes on instance of "object" class.

asked May 13, 2010 at 14:34

4

The built-in object can be instantiated but can't have any attributes set on it. (I wish it could, for this exact purpose.) It doesn't have a __dict__ to hold the attributes.

I generally just do this:

class Object(object):
    pass

a = Object()
a.somefield = somevalue

When I can, I give the Object class a more meaningful name, depending on what kind of data I'm putting in it.

Some people do a different thing, where they use a sub-class of dict that allows attribute access to get at the keys. (d.key instead of d['key'])

Edit: For the addition to your question, using setattr is fine. You just can't use setattr on object() instances.

params = ['attr1', 'attr2', 'attr3']
for p in params:
    setattr(obj.a, p, value)

answered May 13, 2010 at 14:41

FogleBirdFogleBird

71.5k25 gold badges121 silver badges131 bronze badges

7

You could use my ancient Bunch recipe, but if you don't want to make a "bunch class", a very simple one already exists in Python -- all functions can have arbitrary attributes (including lambda functions). So, the following works:

obj = someobject
obj.a = lambda: None
setattr(obj.a, 'somefield', 'somevalue')

Whether the loss of clarity compared to the venerable Bunch recipe is OK, is a style decision I will of course leave up to you.

answered May 13, 2010 at 14:49

Alex MartelliAlex Martelli

823k163 gold badges1202 silver badges1379 bronze badges

14

The mock module is basically made for that.

import mock
obj = mock.Mock()
obj.a = 5

answered Feb 9, 2017 at 15:47

Add property to object python

DunatotatosDunatotatos

1,60614 silver badges24 bronze badges

3

You can also use a class object directly; it creates a namespace:

class a: pass
a.somefield1 = 'somevalue1'
setattr(a, 'somefield2', 'somevalue2')

Add property to object python

answered Jan 5, 2018 at 23:44

ErnestoErnesto

9008 silver badges12 bronze badges

3

There are a few ways to reach this goal. Basically you need an object which is extendable.

obj.a = type('Test', (object,), {})  
obj.a.b = 'fun'  

obj.b = lambda:None

class Test:
  pass
obj.c = Test()

mbarkhau

7,9404 gold badges29 silver badges34 bronze badges

answered May 13, 2010 at 14:48

evilpieevilpie

2,62019 silver badges21 bronze badges

1

Now you can do (not sure if it's the same answer as evilpie):

MyObject = type('MyObject', (object,), {})
obj = MyObject()
obj.value = 42

answered Sep 13, 2013 at 0:32

andreabediniandreabedini

1,2751 gold badge12 silver badges20 bronze badges

1

Try the code below:

$ python
>>> class Container(object):
...     pass 
...
>>> x = Container()
>>> x.a = 10
>>> x.b = 20
>>> x.banana = 100
>>> x.a, x.b, x.banana
(10, 20, 100)
>>> dir(x)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', 
'__getattribute__', '__hash__', '__init__', '__module__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__',     '__sizeof__', 
'__str__', '__subclasshook__', '__weakref__', 'a', 'b', 'banana']

answered Jul 23, 2015 at 20:49

neldorneldor

2312 silver badges2 bronze badges

4

as docs say:

Note: object does not have a __dict__, so you can’t assign arbitrary attributes to an instance of the object class.

You could just use dummy-class instance.

answered May 13, 2010 at 14:43

SilentGhostSilentGhost

293k64 gold badges301 silver badges291 bronze badges

These solutions are very helpful during testing. Building on everyone else's answers I do this in Python 2.7.9 (without staticmethod I get a TypeError (unbound method...):

In [11]: auth = type('', (), {})
In [12]: auth.func = staticmethod(lambda i: i * 2)
In [13]: auth.func(2)
Out[13]: 4

answered Aug 27, 2015 at 20:34

Robpol86Robpol86

1,54520 silver badges16 bronze badges

If we can determine and aggregate all the attributes and values together before creating the nested object, then we could create a new class that takes a dictionary argument on creation.

# python 2.7

class NestedObject():
    def __init__(self, initial_attrs):
        for key in initial_attrs:
            setattr(self, key, initial_attrs[key])

obj = someobject
attributes = { 'attr1': 'val1', 'attr2': 'val2', 'attr3': 'val3' }
obj.a = NestedObject(attributes)
>>> obj.a.attr1
'val1'
>>> obj.a.attr2
'val2'
>>> obj.a.attr3
'val3'

We can also allow keyword arguments. See this post.

class NestedObject(object):
    def __init__(self, *initial_attrs, **kwargs):
        for dictionary in initial_attrs:
            for key in dictionary:
                setattr(self, key, dictionary[key])
        for key in kwargs:
            setattr(self, key, kwargs[key])


obj.a = NestedObject(attr1='val1', attr2='val2', attr3= 'val3')

answered Nov 19, 2018 at 21:59

Add property to object python

HarlemSquirrelHarlemSquirrel

7,6264 gold badges32 silver badges33 bronze badges

Which objects are you using? Just tried that with a sample class and it worked fine:

class MyClass:
  i = 123456
  def f(self):
    return "hello world"

b = MyClass()
b.c = MyClass()
setattr(b.c, 'test', 123)
b.c.test

And I got 123 as the answer.

The only situation where I see this failing is if you're trying a setattr on a builtin object.

Update: From the comment this is a repetition of: Why can't you add attributes to object in python?

answered May 13, 2010 at 14:52

jnevesjneves

1,0147 silver badges7 bronze badges

1

I think the easiest way is through the collections module.

import collections
FinanceCtaCteM = collections.namedtuple('FinanceCtaCte', 'forma_pago doc_pago get_total')
def get_total(): return 98989898
financtacteobj = FinanceCtaCteM(forma_pago='CONTADO', doc_pago='EFECTIVO',
                                get_total=get_total)

print financtacteobj.get_total()
print financtacteobj.forma_pago
print financtacteobj.doc_pago

answered Aug 21, 2020 at 15:58

Add property to object python

PjlPjl

1,74418 silver badges21 bronze badges

Coming to this late in the day but here is my pennyworth with an object that just happens to hold some useful paths in an app but you can adapt it for anything where you want a sorta dict of information that you can access with getattr and dot notation (which is what I think this question is really about):

import os

def x_path(path_name):
    return getattr(x_path, path_name)

x_path.root = '/home/x'
for name in ['repository', 'caches', 'projects']:
    setattr(x_path, name, os.path.join(x_path.root, name))

This is cool because now:

In [1]: x_path.projects
Out[1]: '/home/x/projects'

In [2]: x_path('caches')
Out[2]: '/home/x/caches'

So this uses the function object like the above answers but uses the function to get the values (you can still use (getattr, x_path, 'repository') rather than x_path('repository') if you prefer).

answered Mar 2, 2016 at 2:17

Paul WhippPaul Whipp

15.3k4 gold badges40 silver badges52 bronze badges

if you are looking for chain assignment, to do things such as django model template abstract attribute assigning:

from types import SimpleNamespace


def assign(target, *args, suffix):
    ls = target
    for i in range(len(args) - 1):
        a = args[i]
        ns = SimpleNamespace()
        setattr(ls, a, ns)
        ls = ns
    setattr(ls, args[-1], suffix)
    return ls


a = SimpleNamespace()
assign(a, 'a', 'b', 'c', suffix={'name': 'james'})
print(a.a.b.c)
# {'name': 'james'}

which allows you to pass model as a target, and assign end attribute to it.

answered Apr 25 at 12:50

Add property to object python

WeiloryWeilory

2,01811 silver badges25 bronze badges

This works just fine:

    exec("obj.a."+p)

If you want to set the attribute to some value, do this:

    exec("obj.a."+p+"=(the value here)")

For the value to be a string you will have to use these \" instead of quotation marks unless you have the value stored in a variable.

answered Jul 6 at 17:04

di = {}
for x in range(20):
    name = '_id%s' % x
    di[name] = type(name, (object), {})
    setattr(di[name], "attr", "value")

answered Dec 27, 2013 at 19:41

lmoktolmokto

1319 bronze badges

Other way i see, this way:

import maya.cmds

def getData(objets=None, attrs=None):
    di = {}
    for obj in objets:
        name = str(obj)
        di[name]=[]
        for at in attrs:
            di[name].append(cmds.getAttr(name+'.'+at)[0])
    return di

acns=cmds.ls('L_vest_*_',type='aimConstraint')
attrs=['offset','aimVector','upVector','worldUpVector']

getData(acns,attrs)

leota

1,5582 gold badges12 silver badges33 bronze badges

answered May 13, 2016 at 17:22

Add property to object python

2

How do you add a new property to an object in Python?

Python provides a function setattr() that can easily set the new attribute of an object. This function can even replace the value of the attribute. It is a function with the help of which we can assign the value of attributes of the object.

How do you add values to an object in Python?

To add a single element to a list in Python at the end, you can simply use the append() method. It accepts one object and adds that object to the end of the list on which it is called.

How do you add an attribute to an object?

On the List tab, select the object to which you want to add an attribute. On the Attributes tab, click New Row. In the Attribute field, specify a value.

How would you add a property to an object class?

You can add a property to a previously defined object type by using the prototype property. This defines a property that is shared by all objects of the specified type, rather than by just one instance of the object.