简体   繁体   English

Python中的魔法导入

[英]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 编辑:我应该指定我(卡住)使用Python 2,但是有兴趣看看如何在2或3中解决这个问题

The scenario: I have a package called shapes . 场景:我有一个名为shapes的包。

I have a module in shapes called factory which has a ShapeClassFactory class. 我有一个模块shapes称为factory具有ShapeClassFactory类。 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: 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: 但是,我希望能够以这样的方式编写shapes包,它可以像这样使用:

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. ...这个想法是,如果在shapes找不到成员,它会使用ShapeClassFactory来尝试生成它。

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? 如果ShapeClassFactory无法构建一个类,我不介意抛出一个ImportError - 但是这样的事情甚至可能吗?

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. 您可以通过在初始化时自动构造shapes命名空间中的所有可能对象来完成此操作,只要没有太多可能的类并且预先初始化类的成本不是太大。 You would use code like this in shapes.py: 你可以在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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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