nel*_*687 4 python django python-3.x
关于如何在 Django 中实现服务有任何约定吗?来自 Java 背景,我们为业务逻辑创建服务,并在需要的地方“注入”它们。不确定我是否以错误的方式使用 python/django,但我需要连接到 3rd 方 API,所以我使用 api_service.py 文件来做到这一点。问题是,我想将此服务定义为一个类,而在 Java 中,我可以在任何需要的地方注入这个类,它的行为或多或少像一个单例。是否有类似的东西我可以与 Django 一起使用,或者我应该将服务构建为单例并在某处获取实例,或者甚至只有单独的函数而没有类?
TL;DR没有更多细节很难说,但很可能你只需要一个带有几个普通函数的模块,或者最多只需要几个简单的类。
最长的答案:
Python 不是 Java。您当然可以(从技术上讲我的意思是)使用 Java 风格的设计,但这通常不是最好的做法。
你对要解决的问题的描述有点过于模糊,无法给出具体的答案,但我们至少可以给你一些提示和指示(没有双关语):
1/一切都是对象
在 python 中,一切(好吧,你可以在赋值的 RHS 上找到的一切)都是一个对象,包括模块、类、函数和方法。
结果之一是您不需要任何复杂的依赖注入框架——您只需将所需的对象(模块、类、函数、方法等)作为参数传递即可。
另一个后果是,您不必为所有东西都需要类——一个普通的函数或模块就足够了。
一个典型的用例是策略模式,在 Python 中,它最常使用回调函数(或任何其他可调用的 FWIW)来实现。
2/ python 模块是一个单例。
如上所述,在运行时,python 模块是一个对象(类型module),其属性是在模块顶层定义的名称。
除了一些(病态的)极端情况外,python 模块只为给定进程导入一次,并且保证是唯一的。结合python的“全局”范围实际上只是“模块级”全局的事实,这使模块成为合适的单例,因此这种设计模式实际上已经内置了。
3/一个python类(几乎)是一个单例
Python 类也是对象(类型的实例type,直接或间接),并且 Python 具有classmethods(作用于类本身而不是作用于当前实例的方法)和类级属性(属于类对象本身的属性,而不是到它的实例),所以如果你写一个只有 classmethods 和 class 属性的类,你在技术上有一个单例 - 你可以直接或通过实例使用这个类而没有任何区别,因为 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 通常具有更直接(并且更简单的恕我直言)的方法来实现常见(和不太常见)的设计模式。
wrt/您的具体用例,您将不得不发布更详细的描述,但是来自 Django 项目的“连接到第 3 部分 API”(我假设是 REST api?)是如此微不足道,以至于它真的没有多大保证设计考虑本身。