首页 > 解决方案 > Python/Django 和服务作为类

问题描述

有没有关于如何在 Django 中实现服务的约定?来自 Java 背景,我们为业务逻辑创建服务,并在需要的地方“注入”它们。不确定我是否以错误的方式使用 python/django,但我需要连接到第 3 方 API,所以我使用 api_service.py 文件来执行此操作。问题是,我想将此服务定义为一个类,在 Java 中,我可以在任何需要的地方注入这个类,它的行为或多或少像一个单例。有没有这样的东西我可以与 Django 一起使用,或者我应该将服务构建为单例并在某处获取实例,或者甚至只有单独的函数而没有类?

标签: pythondjangopython-3.x

解决方案


TL;DR没有更多细节很难说,但很可能你只需要一个带有几个普通函数的模块,或者最多只需要几个简单的类。

最长的答案:

Python 不是 Java。您当然可以(从技术上讲,我的意思是)使用 Java 风格的设计,但这通常不是最好的做法。

您对要解决的问题的描述有点含糊,无法给出具体答案,但我们至少可以给您一些提示和指示(不是双关语):

1/ 一切都是对象

在 python 中,一切(嗯,你可以在赋值的 RHS 上找到的一切)都是一个对象,包括模块、类、函数和方法。

结果之一是您不需要任何复杂的依赖注入框架 - 您只需将所需的对象(模块、类、函数、方法等)作为参数传递就可以了。

另一个结果是你不一定需要所有的类——一个普通的函数或模块就足够了。

一个典型的用例是策略模式,在 Python 中,它最常使用回调函数(或任何其他可调用的 FWIW)来实现。

2/ python 模块是一个单例。

如上所述,在运行时,python 模块是一个对象(类型为module),其属性是在模块顶层定义的名称。

除了一些(病态的)极端情况外,python 模块仅针对给定进程导入一次,并且保证是唯一的。结合 python 的“全局”范围实际上只是“模块级”全局的事实,这使得模块成为正确的单例,因此这种设计模式实际上已经内置。

3/一个python类(几乎)是一个单例

Python 类也是对象(类型的实例type,直接或间接),并且 Python 具有classmethods(作用于类本身而不是作用于当前实例的方法)和类级属性(属于类对象本身的属性,而不是到它的实例),所以如果你编写一个只有类方法和类属性的类,从技术上讲,你有一个单例——你可以直接使用这个类,也可以通过实例使用这个类,没有任何区别,因为类方法也可以在实例上调用。

wrt/“作为单例的模块”的主要区别在于,对于类,您可以使用继承......

4/ python 有可调用对象

Python 有“可调用”对象的概念。“可调用”是其类实现__call__()运算符的对象),并且每个这样的对象都可以像函数一样被调用。

这意味着您不仅可以将函数用作对象,还可以将对象用作函数 - IOW,“函子”模式是内置的。这使得在代码的一部分中“捕获”某些上下文并在另一部分中使用该上下文进行计算变得非常容易。

5/一个python类是一个工厂

Python 没有new关键字。Pythonc 类是可调用的,只需调用该类即可完成实例化。

这意味着您实际上可以以相同的方式使用类或函数来获取实例,因此“工厂”模式也是内置的。

6/ python 有计算属性

除了最明显的应用程序(用一对 getter/setter 替换公共属性而不破坏客户端代码)之外,这 - 结合其他功能,如可调用对象等 - 可以证明是非常强大的。事实上,类中定义的函数就是这样变成方法的

7/ Python 是动态的

Python 的对象(通常)是基于 dict 的(有例外,但那些是少数且主要是低级 C 编码的类),这意味着您可以动态添加/替换(甚至删除)属性和方法(因为方法是属性)在每个实例或每个类的基础上。

虽然这不是您想无缘无故地使用的功能,但它仍然是一个非常强大的功能,因为它允许动态自定义对象(请记住,类也是对象),允许比您可以做的更复杂的对象和类创建方案在静态语言中。

但是 Python 的动态特性更进一步——您可以使用类装饰器和/或元类来定制类对象的创建(您可能想查看 Django 模型源代码以获取具体示例),甚至只是动态创建一个使用它的元类和函数字典以及其他类级属性的新类。

再一次,这确实可以使看似复杂的问题变得轻而易举地解决(并避免大量样板代码)。

实际上,Python 公开并允许您连接到它的大部分内部(对象模型、属性解析规则、导入机制等),因此一旦您了解了整个设计以及所有内容如何组合在一起,您就可以真正掌握代码的大部分方面运行时

Python 不是 Java

现在我明白所有这些看起来有点像供应商的目录,但重点是强调 Python 与 Java 的不同之处以及为什么规范的 Java 解决方案 - 或(至少)这些解决方案的规范 Java实现- 通常不能很好地移植到Python 世界。并不是说它们根本不起作用,只是 Python 通常有更直接(而且更简单的恕我直言)的方法来实现常见(和不太常见)的设计模式。

wrt/您的具体用例,您将不得不发布更详细的描述,但是来自 Django 项目的“连接到第 3 部分 API”(我假设是 REST api?)是如此微不足道,以至于它真的不需要太多设计考虑本身。


推荐阅读