简体   繁体   中英

magic imports in Python

Edit: I should have specified I'm (stuck) working w/ Python 2, but would be interested to see how this could be tackled in either 2 or 3

The scenario: I have a package called shapes .

I have a module in shapes called factory which has a ShapeClassFactory class. This class can be passed a string, and it will look in a remote database for data and use that to dynamically define a class, which it returns.

shapes.py:

from .factory import ShapeClassFactory
__all__ = ['ShapeClassFactory']

In practice this package may be used in a variety of other packages & scripts, like so:

from shapes import ShapeClassFactory

Circle = ShapeClassFactory("Circle")
Rect = ShapeClassFactory("Rect")

myCircle = Circle(r=5, fill='red')
mySquare = Rect(x=5, y=5, fill=None)

The problem: The above is all fine. However, I would love to be able to write the shapes package in such a way that it could be used like so:

from shapes import Circle, Rect

myCircle = Circle(r=5, fill='red')
mySquare = Rect(x=5, y=5, fill=None)

...the idea being that if the member isn't found in shapes , it uses ShapeClassFactory to try and generate it.

The difficulty is that the available classes basically aren't known until requested, so a predefined list of class names won't help.

I don't mind throwing an ImportError if ShapeClassFactory fails to build a class -- but is such a thing even possible?

You can do this by automatically constructing all possible objects in the shapes namespace on initialization, as long as there aren't too many possible classes and the cost of initializing the classes up-front isn't too heavy. You would use code like this in shapes.py:

from .factory import ShapeClassFactory

__all__ = ['ShapeClassFactory']

def get_shape_names():
    """Returns all valid shapes that can be passed in to ShapeClassFactory"""
    return ['Circle', 'Rect']  # your own code should query the database

for name in get_shape_names():
    globals()[name] = ShapeClassFactory(name)
    __all__.append(name)

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