![]() |
1
166
我不认为国际奥委会 那个 在蟒蛇中不常见。什么 是 然而,DI/IOC并不常见 框架/容器 . 想想看:di容器是做什么的?它允许你
我们有“连接在一起”和“运行时”的名称:
因此,di容器只不过是动态脚本语言的解释器。实际上,让我重申一下:典型的Java/.net DI容器只不过是一个糟糕的动态脚本语言的蹩脚的解释器,它具有难看的、有时基于XML的语法。 当你用python编程的时候,当你有一个漂亮的、出色的脚本语言可以使用的时候,你为什么要使用一个丑陋的、糟糕的脚本语言呢?实际上,这是一个更普遍的问题:当你用几乎任何一种语言编程时,当你拥有Jython和IronPython时,为什么要使用一种丑陋的、糟糕的脚本语言? 所以,概括一下: 实践 在相同的原因中,DI/IOC在Python中与Java一样重要。这个 实施 然而,di/ioc是内置在语言中的,而且通常非常轻量级,以至于它完全消失了。 (这里有一个简单的类比:在汇编中,一个子程序调用是一个相当重要的处理-你必须保存你的局部变量和寄存器到内存中,保存你的返回地址在某处,改变你调用的子程序的指令指针,安排它以某种方式跳回子例程完成后,将参数放在被调用方可以找到它们的地方,依此类推。IOW:在汇编语言中,“子例程调用”是一种设计模式,在出现像Fortran这样有内置子例程调用的语言之前,人们正在构建自己的“子例程框架”。您是否会说,子例程调用在python中是“不常见的”,仅仅因为您不使用子例程框架?) 顺便说一句:举一个例子,看看把di带入它的逻辑结论是什么样子的 Gilad Bracha 的 Newspeak Programming Language 以及他在这方面的著作: |
![]() |
2
39
其中一部分是模块系统在python中的工作方式。只需从模块中导入,就可以免费获得某种“singleton”。在模块中定义一个对象的实际实例,然后任何客户机代码都可以导入它并实际获得一个工作的、完全构造/填充的对象。 这与Java相反,在这里您不导入对象的实际实例。这意味着您必须自己实例化它们(或者使用某种ioc/di风格的方法)。您可以通过使用静态工厂方法(或实际的工厂类)来减轻必须自己实例化所有内容的麻烦,但是每次实际创建新的方法时仍然会产生资源开销。 |
![]() |
3
35
django很好地利用了控制反转。例如,数据库服务器由配置文件选择,然后框架向数据库客户端提供适当的数据库包装器实例。 不同之处在于python具有一流的类型。数据类型(包括类)本身就是对象。如果您想使用某个特定的类,只需命名该类。例如:
以后的代码可以通过编写以下内容来创建数据库接口:
代替Java和C++需要的样板工厂功能,Python用一行或两行普通代码来完成它。这就是函数式编程与命令式编程的优势所在。 |
![]() |
4
12
已经有好几年没有使用过python了,但我想说的是,它更多的是与它是一种动态类型语言有关。对于一个简单的例子,在Java中,如果我想测试一些适当地写入标准的东西,我可以使用任何打印流中的DI和PASS来捕获正在编写和验证的文本。然而,当我在ruby中工作时,我可以动态地替换stdout上的'puts'方法来进行验证,这样di就完全不在图片中了。如果我创建抽象的唯一原因是测试使用它的类(思考文件系统操作或爪哇中的时钟),那么DI/IOC会在解决方案中造成不必要的复杂性。 |
![]() |
5
9
ioc/di是一个设计概念,但不幸的是,它常常被当作一个适用于某些语言(或打字系统)的概念。我很想看到依赖注入容器在python中变得更加流行。这里有Spring,但这是一个超级框架,它似乎是Java概念的直接端口,而不用太多地考虑“Python方式”。 考虑到python 3中的注释,我决定对一个功能齐全但简单的依赖注入容器进行分析: https://github.com/zsims/dic . 它基于.NET依赖项注入容器中的一些概念(如果您曾经在该空间中玩过的话,IMO是非常棒的),但它与Python概念发生了变化。 |
![]() |
6
8
ioc和di在成熟的python代码中非常常见。由于duck类型,您不需要框架来实现di。
最好的例子是如何使用
django rest框架大量使用di:
让我提醒一下( source ):
|
![]() |
7
7
实际上,用di编写足够干净和紧凑的代码是相当容易的(我想知道,它会不会 蟒蛇的 然后,但无论如何:)),例如,我实际上采用了这种编码方式:
γ
是的,这可以被看作是参数化函数/类的一种简单形式,但是它可以完成它的工作。所以,也许python默认的电池也足够了。 另外,我还在 Dynamically evaluating simple boolean logic in Python . |
![]() |
8
6
我支持“j_ rg w mittag”的回答:“di/ioc的python实现是如此轻量级,以至于它完全消失了”。 为了支持这个语句,看看著名的Martin Fowler从Java移植到Python的例子: Python:Design_Patterns:Inversion_of_Control 从上面的链接可以看到,python中的“container”可以用8行代码编写:
|
![]() |
9
6
看起来人们真的不知道依赖注入和控制反转意味着什么了。 使用控制反转的实践是拥有依赖于其他类或函数的类或函数,但与其用函数类代码创建实例,不如将其作为参数接收,这样就可以实现松耦合。这有很多好处,因为它更具可测试性,有助于构建liskov替换原则。 你看,通过使用接口和注入,你的代码变得更容易维护,因为你可以很容易地改变行为,因为你不必重写类的一行代码(可能是DI配置中的一两行)来改变它的行为,因为类所等待的接口可以独立变化,只要它们遵循接口。保持代码解耦和易于维护的最佳策略之一是至少遵循单一的责任性、替换和依赖性反转原则。 如果您可以自己在包中实例化一个对象并导入它来自己注入它,那么DI库有什么好处?选择的答案是正确的,因为Java没有程序段(类之外的代码),所有这些都进入了无聊的配置XML,因此需要一个类来实例化和注入依赖于懒惰的加载方式的依赖关系,这样就不会影响您的性能,而Python只需编写代码即可。对代码的“过程”(类外代码)部分的注入 |
![]() |
10
4
我认为由于python的动态特性,人们并不经常看到需要另一个动态框架。当类从新样式的“object”继承时,可以动态创建新变量( https://wiki.python.org/moin/NewClassVsClassicClass ) 即 在普通的python中:
不过看看 https://github.com/noodleflake/pyioc 这可能就是你要找的。 即 在PYOC
|
![]() |
11
2
我的2美分是,在大多数Python应用程序中,你不需要它,即使你需要它,也有可能是许多Java仇恨者(以及那些认为是开发者的无能的小提琴手)认为它是不好的东西,只是因为它在Java中很受欢迎。 当有复杂的对象网络时,ioc系统实际上是有用的,其中每个对象可能是多个其他对象的依赖关系,而反过来又是自身对其他对象的依赖关系。在这种情况下,您需要定义所有这些对象一次,并有一种机制根据尽可能多的隐式规则将它们自动组合在一起。如果您还需要由应用程序用户/管理员以简单的方式定义配置,那么这就是希望ioc系统能够从简单的xml文件(即配置文件)中读取其组件的另一个原因。 典型的python应用程序要简单得多,只是一堆脚本,没有这么复杂的体系结构。就我个人而言,我知道ioc实际上是什么(与那些在这里写下某些答案的人相反),而且在我有限的python经验中,我从来没有感觉到需要它(而且我也没有在任何地方使用spring,而不是当它所提供的优势不能证明它的开发开销是合理的时)。 也就是说,有些python情况下,ioc方法实际上是有用的,实际上,我在这里读到django使用它。 上面的推理可以应用于Java世界中的面向方面编程,不同之处在于AOP真正值得的情况的数量甚至更有限。 |
![]() |
12
-1
我同意@jorg的观点,即di/ioc在python中是可能的、更容易的、甚至更漂亮的。缺少的是支持它的框架,但也有一些例外。举几个我想到的例子:
|
![]() |
13
-2
在我看来,像依赖注入这样的东西是一个僵硬和过于复杂的框架的症状。当代码主体变得太重而不易更改时,您发现自己必须选择其中的一小部分,为它们定义接口,然后允许人们通过插入这些接口的对象来更改行为。这一切都很好,但最好一开始就避免这种复杂性。 这也是静态类型语言的症状。当你唯一需要表达抽象的工具是继承的时候,那就是你在任何地方使用的工具。尽管如此,C++还是非常相似,但从来没有引起Java开发人员对建设者和接口的着迷。以写作为代价的灵活和可扩展的梦想很容易让人忘却。 far too much generic code with little real benefit . 我认为这是一种文化。 通常,我认为python人员习惯于为工作选择合适的工具,这是一个连贯而简单的整体,而不是一个真正的工具(有上千个可能的插件),它可以做任何事情,但却提供了一系列可能的配置排列。在必要的地方仍然有可互换的部分,但是由于duck类型的灵活性和语言的相对简单性,不需要定义固定接口的大形式主义。 |
![]() |
14
-2
与Java中的强类型性质不同。python的duck类型行为使得传递对象变得非常容易。 Java开发人员专注于构造对象的类结构和关系,同时保持事物的灵活性。国际奥委会对实现这一目标极为重要。 python开发人员正在集中精力完成工作。当他们需要的时候,他们就把课程连接起来。他们甚至不用担心班级的类型。只要它能呱呱叫,它就是鸭子!这种性质不给国际奥委会留下任何空间。 |