DZone
Integration Zone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Integration Zone > Loading Classes From Modules With Reflection in Python (Imp Module)

Loading Classes From Modules With Reflection in Python (Imp Module)

Chase Seibert user avatar by
Chase Seibert
·
May. 02, 14 · Integration Zone · Interview
Like (0)
Save
Tweet
6.69K Views

Join the DZone community and get the full member experience.

Join For Free

For a dynamic language, it’s more difficult than it needs to be to import a module dynamically in Python. It’s very easy to just from foo import bar, but what if you want to load a list of things and all you have is a string representation of each one, for example foo.bar?

One use case for this is for configuration. Django uses this pattern to initialize apps via its INSTALLED_APPS setting. For example, the default settings looks like this:

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'polls',
)

At some point, Django does the equivalent of a from django.contrib import admin and then starts poking around for urls and models modules. I’m guessing this is done primarily to avoid circular import issues; if Django imports your apps as normal, but your apps turn around and import Django, then you’ve got a problem.

I wanted to reproduce this pattern myself, and it was a little harder than I expected. Python provides an imp for just this occasion. But, from the docs:

At some point, Django does the equivalent of a from django.contrib import admin and then starts poking around for urls and models modules. I’m guessing this is done primarily to avoid circular import issues; if Django imports your apps as normal, but your apps turn around and import Django, then you’ve got a problem.

"This function does not handle hierarchical module names (names containing dots). In order to find P.M, that is, submodule M of package P, use find_module() and load_module() to find and load package P, and then use find_module() with the path argument set to P.__path__. When P itself has a dotted name, apply this recipe recursively."

So, it’s basically is a pain the balls to deal with. Here is a working example:

import imp


THINGS_TO_IMPORT = (
    'utils.misc.MyClass1',   # class
    'utils.misc.foo',  # constant
    'utils.bar',  # from __init__.py
    'utils.misc',  # module
)


def import_from_dotted_path(dotted_names, path=None):
    """ import_from_dotted_path('foo.bar') -> from foo import bar; return bar """
    next_module, remaining_names = dotted_names.split('.', 1)
    fp, pathname, description = imp.find_module(next_module, path)
    module = imp.load_module(next_module, fp, pathname, description)
    if hasattr(module, remaining_names):
        return getattr(module, remaining_names)
    if '.' not in remaining_names:
        return module
    return import_from_dotted_path(remaining_names, path=module.__path__)


if __name__ == "__main__":
    for name_of_thing in THINGS_TO_IMPORT:
        thing = import_from_dotted_path(name_of_thing)
        print '%s => %r' % (name_of_thing, thing)
And the output as expected:
utils.misc.MyClass1 => <class 'misc.MyClass1'>
utils.misc.foo => {'bar': 7}
utils.bar => 'foo'
utils.misc => <module 'utils' from 'myapp/utils/__init__.pyc'>

Here is a directory listing of my test modules, in case this isn’t clear.

./utils/__init__.py:

bar = 'foo'


./utils/misc.py:

class MyClass1(object):
    pass

foo = {'bar': 7}









Python (language) app Django (web framework) Use case IT Listing (computer) Strings Testing Clear (Unix) Directory

Published at DZone with permission of Chase Seibert, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Build a Data Pipeline on AWS With Kafka, Kafka Connect, and DynamoDB
  • What's the Difference Between Static Class vs. Singleton Patterns in C#?
  • Understand Source Code — Deep Into the Codebase, Locally and in Production
  • 10 Programming Habits a Web Developer Should Embrace

Comments

Integration Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo