构建可插拔应用程序:如何包含流行库的分支并防止名称冲突?

Posted

技术标签:

【中文标题】构建可插拔应用程序:如何包含流行库的分支并防止名称冲突?【英文标题】:Building pluggable apps: how to include forks of popular libraries and prevent name conflicts? 【发布时间】:2012-08-10 09:28:10 【问题描述】:

我正在构建一个我试图保持可插拔的应用程序。唯一的问题是我需要稍微修改django-mailer,以便我的应用程序可以跟踪已发送/未发送的电子邮件并访问电子邮件内容。

确保这不会与使用 django-mailer 的其他人或我决定为自己的应用分叉/调整的任何其他 python 库冲突的最佳方法是什么?

我应该重命名我的 fork 中的 mailer 及其所有相关导入吗?我错过了一些更容易的东西吗?

【问题讨论】:

你的 django-mailer 模块是否会为其他应用程序破坏它?如果没有,那么别担心,每个人都可以使用你的版本。 您可以在自己的应用程序中接收来自 django-mailer 的信号并且保持不变?听起来你试图用它做的事情不需要实际修改。 @Spacedman 它会破坏它,因为我想修改 MessageLog 对象上的字段。问题是核心邮件engine 类在创建MessageLog 时立即delete()s 消息对象。我想我可以编写自己的模型来存储 MessageLog -> 消息关系,并基本上复制并粘贴 mailer.engine 以添加 ML->M 关系。 @moopet - 信号短暂地掠过我的脑海。您将如何从 Message 到 MessageLog 进行通信? 【参考方案1】:

你可以用一个函数来解决它。创建一个同时做这两件事的函数:

确保事后可以得到想要的东西 确保消息已发送。

或者你可以做一些更重的管道。确保把它记录好,并尽量让其他人不要在家里为了每一个徒劳的目的尝试这个,而是联系 Django 或 Django-mailer 团队,询问他们是否可以安排更好的解决方案。

装饰来自 django.core.mail 模块的 EmailMessage 类:确保在成功发送消息后,您想要的信息也会传递到其他地方。

# wrappedmailer.py
from django.core.mail import EmailMessage

class WrappedEmailMessage(object):
    def __init__(self, message):
        self.__message = message
        # more initialization

    # override all EmailMessage methods:
    # do what you want with what is provided,
    # then return self.__message.method(...)

然后当你的应用程序初始化时,在加载 django-mailer 之前,你可以执行以下操作:

   import django.core.mail
   import newmailer

   django.core.mail.EmailMessage = newmailer.WrappedEmailMessage

django.core.mail 模块保留在同一个 Python 进程中的缓存中,因此每当导入 django.core.mail 时,EmailMessage 类实际上就是 WrappedEmailMessage 类。

【讨论】:

我喜欢包装 EmailMessage 的想法。不幸的是,我的主要问题仍然存在:我需要修改 django-mailer 本身(或任何其他应用程序)并好奇如何处理它。这些是无法猴子修补的更改:模型级别的更改。如何防止它与 django-mailers 冲突?重命名包和其中定义的每个导入是否标准? 如果更改django-mailer 是主要要求,请将其复制到包mypackages.mymailer(不是mypackages.mailer,这样内容类型框架就不会太混乱)。然后根据需要更改代码。然后您仍然可以使用这两个版本,但您将始终知道您使用的是原始版本还是修改后的版本。 所以重命名所有内容是标准的,这样新邮件程序就不会导入旧邮件程序?保持所有导入行更新似乎是一项不错的工作,但我真的看不到另一个解决方案(这个问题的目的)。这在包含大量代码的更大包中会非常糟糕。 所以,小就是美。

以上是关于构建可插拔应用程序:如何包含流行库的分支并防止名称冲突?的主要内容,如果未能解决你的问题,请参考以下文章

阿里开源可插拔 React 跨端框架- UmiJS

子类化 Flask 可插拔视图以实现可扩展功能的最佳方式

具有 HCS 可插拔共识的 Corda

Android如何实现可插拔配置?

理解及应用 Oracle 12c 插拔数据库

如何实现可插拔配置?