从字符串中获取类对象

时间:2013-07-03 10:37:35

标签: python django string class getattr

我正在编写以下内容来为我的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()
        ]
    )

我有模块overviewcontent,分别有类OverviewContentUploader

如果view数组(例如,[ 'Index' ]包含单个元素,我使用模块的大写形式(例如,overview变为Overview)来生成路线:

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

如果它包含两个元素(例如[ 'Uploader', 'Default' ]),则第一个元素指定类名,第二个元素指定方法:

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

您可能已经注意到,问题在于我使用getattr(),其第一个参数需要类引用。所以,我的问题是是否有任何方法可以从包含所述类对象的标识符的字符串中获取类对象,例如,来自Uploader的{​​{1}}类。

作为免责声明,这些不是我的确切路线,只是一个例子。当然,我的整体设计也欢迎进一步的评论。

1 个答案:

答案 0 :(得分:4)

我说有两种常见的做法。考虑以下示例:

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