简体   繁体   中英

How do you import a list of classes from a module?

Is there a way to import only a specific, predefined list of classes from a Python module? For example, say that I had modules a.py and b.py in the same directory with the following code:

#a.py
class Foo(object):
    '''definition of class Foo goes here'''

class Bar(object):
    '''definition of class Bar goes here'''

aTypes = [Foo, Bar]

_

#b.py
from a import aTypes

print Foo

Running b.py causes, of course, the print Foo line to raise a NameError . I didn't really think that this would work (the import statement in b.py gives me an a.Foo type instead of a Foo type), but I can't figure out the right syntax. Is there an alternative to from a import aTypes that gives the desired behavior?

You could import the names directly:

from a import Foo, Bar

Alternately, you could define __all__ in a.py :

__all__ = ['Foo', 'Bar']

and then do a wildcard import in b.py :

from a import *

For just two names though, it would be easier to use the first solution.

Supposing you really do need to do this (deal with list of types) and can't use tricks like __all__ that only work once (one such special list per module), then:

def gettypes(types):
    thismodule = sys.modules[__name__]
    for t in types:
        setattr(thismodule, t.__name__, t)

Use it like this:

import a
gettypes(a.aTypes)

I'm finding it difficult to imagine why you'd need this, but that's not my problem ;-)

Note the use of __name__ means this doesn't work for symbols in general, only for classes, modules, functions and anything else I've forgotten (or at a pinch for objects of your own design that have a __name__ ). It also won't work for things you've aliased in the module, for example by writing Baz = Bar in the module and then using Baz in the list. If the list was ['Foo', 'Bar'] instead of [Foo, Bar] , and you also passed the source module into gettypes , then you could avoid those restrictions.

You can define __all__ at the module level of a.py :

__all__ = ['Foo', 'Bar']

This will allow you to import it in the following way:

from a import *

Of course, this behaviour isn't always encouraged, and the alternative is preferred:

from a import Foo, Bar

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM