How to create a new unknown or dynamic/expando object in Python

后端 未结 5 385
我在风中等你
我在风中等你 2021-02-02 07:07

In python how can we create a new object without having a predefined Class and later dynamically add properties to it ?

example:

dynamic_object = Dynami         


        
5条回答
  •  粉色の甜心
    2021-02-02 07:38

    If you take metaclassing approach from @Martijn's answer, @Ned's answer can be rewritten shorter (though it's obviously less readable, but does the same thing).

    obj = type('Expando', (object,), {})()
    obj.foo = 71
    obj.bar = 'World'
    

    Or just, which does the same as above using dict argument:

    obj = type('Expando', (object,), {'foo': 71, 'bar': 'World'})()
    

    For Python 3, passing object to bases argument is not necessary (see type documentation).

    But for simple cases instantiation doesn't have any benefit, so is okay to do:

    ns = type('Expando', (object,), {'foo': 71, 'bar': 'World'})
    

    At the same time, personally I prefer a plain class (i.e. without instantiation) for ad-hoc test configuration cases as simplest and readable:

    class ns:
        foo = 71
        bar = 'World'
    

    Update

    In Python 3.3+ there is exactly what OP asks for, types.SimpleNamespace. It's just:

    A simple object subclass that provides attribute access to its namespace, as well as a meaningful repr.

    Unlike object, with SimpleNamespace you can add and remove attributes. If a SimpleNamespace object is initialized with keyword arguments, those are directly added to the underlying namespace.

    import types
    obj = types.SimpleNamespace()
    obj.a = 123
    print(obj.a) # 123
    print(repr(obj)) # namespace(a=123)
    

    However, in stdlib of both Python 2 and Python 3 there's argparse.Namespace, which has the same purpose:

    Simple object for storing attributes.

    Implements equality by attribute names and values, and provides a simple string representation.

    import argparse
    obj = argparse.Namespace()
    obj.a = 123
    print(obj.a) # 123 
    print(repr(obj)) # Namespace(a=123)
    

    Note that both can be initialised with keyword arguments:

    types.SimpleNamespace(a = 'foo',b = 123)
    argparse.Namespace(a = 'foo',b = 123)
    

提交回复
热议问题