Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get class object from string

I'm writing the following to generate URLs for my urls.py:

urls = {
    'overview': {
        r'^$':          [ 'Index' ],
        r'^/account$':  [ 'Account' ],
    },

    'content': {
        r'^/content$':        [ 'Index' ]
        r'^/content/upload$': [ 'Uploader', 'Default' ]
    }

}

urlpatterns = patterns('')

for module, spec in urls.iteritems():
    urlpatterns += patterns('views.'+ module,
        [
                url(regex, (getattr(module.capitalize() , 'as_view'))(), action=view[0])
            if len(view) == 1 else
                url(regex, (getattr(view[0], 'as_view'))(), action=view[1])
            for regex, view in spec.iteritems()
        ]
    )

I have modules overview and content, with classes Overview, and Content and Uploader, respectively.

If the view array (e.g., [ 'Index' ] contains a single element, I use the capitalized form of the module (e.g., overview becomes Overview) to generate the route:

url(r'^$', Overview.as_view(), action='Index')

whereas if it contains two elements, (e.g., [ 'Uploader', 'Default' ]), the first element specifies the class name and the second the method:

url(r'^$', Uploader.as_view(), action='Default')

As you may have noticed, the issue is with my use of getattr(), whose first argument requires a class reference. So, my question is whether there is any way to get the class object from a string that contains the identifier of said class object, e.g., the Uploader class from 'Uploader'.

As a disclaimer these are not my exact routes, just an example. And of course further comments are welcome with respect to my overall design here as well.


1 Answers

I'd say there are two common ways of doing it. Consider example below:

from random import choice


class A(object):
    def __init__(self):
        self.name = 'in A'


class B(object):
    def __init__(self):
        self.name = 'in B'


class C(object):
    def __init__(self):
        self.name = 'in C'

if __name__ == "__main__":
    classes = ['A', 'B', 'C']
    class_name = choice(classes)
    print class_name

    # 1st way
    obj = globals()[class_name]()
    print obj.name

    # 2nd way
    import sys
    obj = getattr(sys.modules['__main__'], class_name)()
    print obj.name

    # 3rd way - not recommended
    obj = eval(class_name)()
    print obj.name
like image 159
matino Avatar answered Oct 22 '25 00:10

matino



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!