为什么IoC / DI在Python中不常见?

本文翻译自:Why is IoC / DI not common in Python?

In Java IoC / DI is a very common practice which is extensively used in web applications, nearly all available frameworks and Java EE. 在Java中, IoC / DI是一种非常常见的做法,广泛用于Web应用程序,几乎所有可用的框架和Java EE。 On the other hand, there are also lots of big Python web applications, but beside of Zope (which I've heard should be really horrible to code) IoC doesn't seem to be very common in the Python world. 另一方面,也有很多大的Python Web应用程序,但除了Zope(我听说代码应该非常糟糕),IoC在Python世界中似乎并不常见。 (Please name some examples if you think that I'm wrong). (如果你认为我错了,请说出一些例子)。

There are of course several clones of popular Java IoC frameworks available for Python, springpython for example. 当然有几个流行的Java IoC框架克隆可用于Python,例如springpython But none of them seems to get used practically. 但它们似乎都没有被实际使用。 At least, I've never stumpled upon a Django or sqlalchemy + <insert your favorite wsgi toolkit here> based web application which uses something like that. 至少,我从来没有在一个stumpled Django的SQLAlchemy的 + <insert your favorite wsgi toolkit here> ,它使用类似的东西,基于Web应用程序。

In my opinion IoC has reasonable advantages and would make it easy to replace the django-default-user-model for example, but extensive usage of interface classes and IoC in Python looks a bit odd and not »pythonic«. 在我看来,IoC具有合理的优势,并且可以很容易地替换django-default-user-model,但是在Python中广泛使用接口类和IoC看起来有点奇怪而不是“pythonic”。 But maybe someone has a better explanation, why IoC isn't widely used in Python. 但也许有人有更好的解释,为什么IoC没有在Python中广泛使用。


#1楼

参考:https://stackoom.com/question/akoS/为什么IoC-DI在Python中不常见


#2楼

I agree with @Jorg in the point that DI/IoC is possible, easier and even more beautiful in Python. 我同意@Jorg的观点,认为DI / IoC是可行的,在Python中更容易,更美观。 What's missing is the frameworks supporting it, but there are a few exceptions. 缺少的是支持它的框架,但也有一些例外。 To point a couple of examples that come to my mind: 要指出一些我想到的例子:

  • Django comments let you wire your own Comment class with your custom logic and forms. Django注释允许您使用自定义逻辑和表单连接自己的Comment类。 [More Info] [更多信息]

  • Django let you use a custom Profile object to attach to your User model. Django允许您使用自定义Profile对象附加到您的User模型。 This is not completely IoC but is a good approach. 这不是完全IoC,但是一个很好的方法。 Personally I'd like to replace the hole User model as the comments framework does. 就个人而言,我想像评论框架那样替换漏洞用户模型。 [More Info] [更多信息]


#3楼

In my opinion, things like dependency injection are symptoms of a rigid and over-complex framework. 在我看来,依赖注入之类的东西是僵化和过于复杂的框架的症状。 When the main body of code becomes much too weighty to change easily, you find yourself having to pick small parts of it, define interfaces for them, and then allowing people to change behaviour via the objects that plug into those interfaces. 当代码的主体变得过于庞大而无法轻易更改时,您会发现自己必须选择它的一小部分,为它们定义接口,然后允许人们通过插入这些接口的对象来改变行为。 That's all well and good, but it's better to avoid that sort of complexity in the first place. 这一切都很好,但最好首先避免这种复杂性。

It's also the symptom of a statically-typed language. 这也是静态类型语言的症状。 When the only tool you have to express abstraction is inheritance, then that's pretty much what you use everywhere. 当你必须表达抽象的唯一工具是继承时,那几乎就是你在任何地方使用的工具。 Having said that, C++ is pretty similar but never picked up the fascination with Builders and Interfaces everywhere that Java developers did. 话虽如此,C ++非常相似,但从未在Java开发人员所做的任何地方发现构建器和接口的魅力。 It is easy to get over-exuberant with the dream of being flexible and extensible at the cost of writing far too much generic code with little real benefit . 以编写太多通用代码而没有实际利益为代价的灵活性和可扩展性的梦想很容易变得过于旺盛。 I think it's a cultural thing. 我认为这是一种文化的东西。

Typically I think Python people are used to picking the right tool for the job, which is a coherent and simple whole, rather than the One True Tool (With A Thousand Possible Plugins) that can do anything but offers a bewildering array of possible configuration permutations. 通常我认为Python人习惯于为工作挑选合适的工具,这是一个连贯而简单的整体,而不是One True Tool(有一千个可能的插件)可以做任何事情,但提供了一系列令人眼花缭乱的可能的配置排列。 There are still interchangeable parts where necessary, but with no need for the big formalism of defining fixed interfaces, due to the flexibility of duck-typing and the relative simplicity of the language. 在必要时仍然可以互换部分,但由于鸭子类型的灵活性和语言的相对简单性,不需要定义固定接口的大型形式。


#4楼

Haven't used Python in several years, but I would say that it has more to do with it being a dynamically typed language than anything else. 几年没有使用过Python,但我会说它与动态类型语言有关,而不是其他任何东西。 For a simple example, in Java, if I wanted to test that something wrote to standard out appropriately I could use DI and pass in any PrintStream to capture the text being written and verify it. 举一个简单的例子,在Java中,如果我想测试那些写入标准的东西,我可以使用DI并传入任何PrintStream来捕获正在编写的文本并进行验证。 When I'm working in Ruby, however, I can dynamically replace the 'puts' method on STDOUT to do the verify, leaving DI completely out of the picture. 然而,当我在Ruby中工作时,我可以动态地替换STDOUT上的'puts'方法来进行验证,从而使DI完全脱离图片。 If the only reason I'm creating an abstraction is to test the class that's using it (think File system operations or the clock in Java) then DI/IoC creates unnecessary complexity in the solution. 如果我创建抽象的唯一原因是测试使用它的类(想想文件系统操作或Java中的时钟),那么DI / IoC会在解决方案中创建不必要的复杂性。


#5楼

Part of it is the way the module system works in Python. 部分原因是模块系统在Python中的工作方式。 You can get a sort of "singleton" for free, just by importing it from a module. 你可以免费获得一种“单身”,只需从模块中导入即可。 Define an actual instance of an object in a module, and then any client code can import it and actually get a working, fully constructed / populated object. 在模块中定义对象的实际实例,然后任何客户端代码都可以导入它并实际获得一个工作的,完全构造/填充的对象。

This is in contrast to Java, where you don't import actual instances of objects. 这与Java不同,在Java中您不导入实际的对象实例。 This means you are always having to instantiate them yourself, (or use some sort of IoC/DI style approach). 这意味着你总是必须自己实例化它们(或者使用某种IoC / DI风格的方法)。 You can mitigate the hassle of having to instantiate everything yourself by having static factory methods (or actual factory classes), but then you still incur the resource overhead of actually creating new ones each time. 您可以通过使用静态工厂方法(或实际工厂类)来减轻必须自己实例化所有内容的麻烦,但是每次实际创建新方法时仍然会产生资源开销。


#6楼

I don't actually think that DI/IoC are that uncommon in Python. 我实际上并不认为DI / IoC在Python 不常见。 What is uncommon, however, are DI/IoC frameworks/containers . 什么不常见的,但是,是DI / IoC 框架/容器

Think about it: what does a DI container do? 想想看:DI容器有什么作用? It allows you to 它允许你

  1. wire together independent components into a complete application ... 将独立组件连接成一个完整的应用程序......
  2. ... at runtime. ......在运行时。

We have names for "wiring together" and "at runtime": 我们有“连接在一起”和“在运行时”的名称:

  1. scripting 脚本
  2. dynamic 动态

So, a DI container is nothing but an interpreter for a dynamic scripting language. 因此,DI容器只不过是动态脚本语言的解释器。 Actually, let me rephrase that: a typical Java/.NET DI container is nothing but a crappy interpreter for a really bad dynamic scripting language with butt-ugly, sometimes XML-based, syntax. 实际上,让我重新说一下:一个典型的Java / .NET DI容器只不过是一个糟糕的解释器,用于一个非常糟糕的动态脚本语言,它有一种非常丑陋的,有时候是基于XML的语法。

When you program in Python, why would you want to use an ugly, bad scripting language when you have a beautiful, brilliant scripting language at your disposal? 当你用Python编程时,为什么你会想要使用一种丑陋的,糟糕的脚本语言,当你拥有一个漂亮,优秀的脚本语言时? Actually, that's a more general question: when you program in pretty much any language, why would you want to use an ugly, bad scripting language when you have Jython and IronPython at your disposal? 实际上,这是一个更普遍的问题:当您使用几乎任何语言进行编程时,为什么当您使用Jython和IronPython时,您是否想要使用一种丑陋,糟糕的脚本语言?

So, to recap: the practice of DI/IoC is just as important in Python as it is in Java, for exactly the same reasons. 因此,回顾一下:出于完全相同的原因,DI / IoC的实践在Python中与在Java中一样重要。 The implementation of DI/IoC however, is built into the language and often so lightweight that it completely vanishes. 然而,DI / IoC的实现是内置于语言中的,并且通常非常轻巧,完全消失。

(Here's a brief aside for an analogy: in assembly, a subroutine call is a pretty major deal - you have to save your local variables and registers to memory, save your return address somewhere, change the instruction pointer to the subroutine you are calling, arrange for it to somehow jump back into your subroutine when it is finished, put the arguments somewhere where the callee can find them, and so on. IOW: in assembly, "subroutine call" is a Design Pattern, and before there were languages like Fortran which had subroutine calls built in, people were building their own "subroutine frameworks". Would you say that subroutine calls are "uncommon" in Python, just because you don't use subroutine frameworks?) (这里有一个简单的比喻:在汇编中,子程序调用是一个非常重要的交易 - 你必须将你的局部变量和寄存器保存到内存,保存你的返回地址,将指令指针更改为你调用的子程序,安排它以某种方式跳回你的子程序完成后,将参数放在被调用者可以找到它们的地方,等等.IOW:在汇编中,“子程序调用”是一个设计模式,之前有类似的语言Fortran内置了子程序调用,人们正在构建自己的“子程序框架”。你会说Python中的子程序调用是“不常见的”,只是因为你没有使用子程序框架吗?)

BTW: for an example of what it looks like to take DI to its logical conclusion, take a look at Gilad Bracha 's Newspeak Programming Language and his writings on the subject: 顺便说一句:有关将DI 纳入其逻辑结论的示例,请查看Gilad Bracha的新闻编程语言及其关于该主题的着作:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值