質問

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.

役に立ちましたか?

解決

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
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top