动态类加载解释 - cucy/djoscar GitHub Wiki
动态类加载是使奥斯卡广泛定制的基础。因此,理解它是如何工作的,因为大多数定制都依赖于它。
It is achieved by oscar.core.loading.get_classes()
and its single-class cousin get_class()
. Wherever feasible, Oscar’s codebase uses get_classes
instead of a regular import statement:
它是由奥斯卡.Calp.Load .GETX类()及其单个类表兄弟GETX类()实现的。在可行的情况下,奥斯卡的代码库使用GETH类而不是常规的导入语句:
from oscar.apps.shipping.repository import Repository
被替换为
from oscar.core.loading import get_class
Repository = get_class('shipping.repository', 'Repository')
几乎所有的类都是这样做的:视图、模型、应用程序实例等。可以通过GETSH类导入的每个类都被重写。
wyh?
This structure enables a project to create a local shipping.repository
module, and optionally subclass the class from oscar.app.shipping.repository
. When Oscar tries to load the Repository
class, it will load the one from your local project.
这种结构使项目能够创建一个本地SpangPield.RealStk模块,并可选地从OsCAR.App.SpPiang.RealStk中实现类的子类。当奥斯卡试图加载存储库类时,它将加载本地项目中的一个。
This way, most classes can be overridden with minimal duplication, as only the to-be-changed classes have to be altered. They can optionally inherit from Oscar’s implementation, which often amounts to little more than a few lines of custom code for changes to core behaviour.
Seen on a bigger scale, this structures enables Oscar to ship with classes with minimal assumptions about the domain, and make it easy to modify behaviour as needed. 这样,大多数类都可以用最少的重复来重写,因为只有要更改的类才能被修改。它们可以从奥斯卡的实现中继承,这通常意味着对核心行为的更改的几行自定义代码。 从更大的尺度上看,这种结构使奥斯卡能够以最小的假设来对类进行装运,并且可以很容易地根据需要修改行为。
How it works
The get_class
function looks through your INSTALLED_APPS
for a matching app and will attempt to load the custom class from the specified module. If the app isn’t overridden or the custom module doesn’t define the class, it will fall back to the default Oscar class.
GETHOLL类函数通过一个匹配的应用程序查看您的安装程序,并尝试从指定的模块加载自定义类。如果应用程序未被重写,或者自定义模块不定义类,则它将返回默认的奥斯卡类。
In practice 在实践中
For get_class
to pick up the customised class, the Oscar apps need to be forked. The process is detailed and illustrated with examples in Customising Oscar. It is usually enough to call oscar_fork_app
and replace the app in INSTALLED_APPS
.
对于GETH类来选择定制类,奥斯卡应用程序需要分叉。该过程是详细的,并举例说明定制奥斯卡。通常调用OsCARY-FurkYApp并替换应用程序中的应用程序是足够的。
get_class
in your own code 在你自己的代码中使用“GETH类”
Using Generally, there is no need for get_class
in your own code as the location of the module for the class is known. Some Oscar developers nonetheless use get_class
when importing classes from Oscar. This means that if someday the class is overridden, it will not require code changes. Care should be taken when doing this, as this is a tricky trade-off between maintainability and added complexity. Please note that we cannot recommend ever using get_model
in your own code. Model initialisation is a tricky process and it’s easy to run into circular import issues.
一般来说,在您自己的代码中不需要“GETH类”,因为该类的模块的位置是已知的。然而,一些奥斯卡开发人员在从奥斯卡导入类时使用“GETH类”。这意味着如果有一天类被重写,它将不需要代码更改。这样做时应该小心,因为这是可维护性和增加的复杂性之间微妙的权衡。请注意,我们不能推荐在您自己的代码中使用“GETYOME模型”。模型初始化是一个棘手的过程,很容易遇到循环导入问题。
重写动态类加载行为
In some cases it may be necessary to customise the logic used by Oscar to dynamically load classes. You can do this by supplying your own class loader function to the OSCAR_DYNAMIC_CLASS_LOADER
setting:
在某些情况下,可能需要定制奥斯卡用来动态加载类的逻辑。您可以通过将自己的类加载器函数提供给'OsCARDyjixCyrasyLoad’设置来实现这一点:
OSCAR_DYNAMIC_CLASS_LOADER = ‘myproject.custom_class_loader’
将一个点式Python路径提供给一个调用相同的参数的可调用的
default_class_loader().
testing
您可以通过尝试从模块中获得类来测试您的重写是否工作:
>>> from oscar.core.loading import get_class
>>> get_class('shipping.repository', 'Repository')
yourproject.shipping.repository.Repository # it worked!