How can I create an object and add attributes to it?

前端 未结 16 1694
长情又很酷
长情又很酷 2020-11-28 00:36

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         


        
相关标签:
16条回答
  • 2020-11-28 01:06

    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.

    0 讨论(0)
  • 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.

    0 讨论(0)
  • 2020-11-28 01:07

    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
    
    0 讨论(0)
  • 2020-11-28 01:07

    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).

    0 讨论(0)
  • 2020-11-28 01:09

    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)
    
    0 讨论(0)
  • 2020-11-28 01:12
    di = {}
    for x in range(20):
        name = '_id%s' % x
        di[name] = type(name, (object), {})
        setattr(di[name], "attr", "value")
    
    0 讨论(0)
提交回复
热议问题