Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 有什么不好的地方吗_Python_Django_Thread Local - Fatal编程技术网

Python 有什么不好的地方吗

Python 有什么不好的地方吗,python,django,thread-local,Python,Django,Thread Local,Django世界的每个人似乎都讨厌当地人(,)。我读过阿明关于这个()的文章,但大部分都是关于这个()的,这篇文章不好,因为它不雅观 我有一个场景,在这个场景中,本地人会让事情变得非常简单。(我有一个应用程序,人们会有子域,因此所有模型都需要访问当前子域,如果threadlocals的唯一问题是它们不雅观,或者代码脆弱,那么从请求传递它们是不值得的。) 另外,许多Java框架似乎经常使用threadlocals,那么它们的情况与Python/Django的情况有什么不同呢?在处理多个线程时,您希

Django世界的每个人似乎都讨厌当地人(,)。我读过阿明关于这个()的文章,但大部分都是关于这个()的,这篇文章不好,因为它不雅观

我有一个场景,在这个场景中,本地人会让事情变得非常简单。(我有一个应用程序,人们会有子域,因此所有模型都需要访问当前子域,如果threadlocals的唯一问题是它们不雅观,或者代码脆弱,那么从请求传递它们是不值得的。)


另外,许多Java框架似乎经常使用threadlocals,那么它们的情况与Python/Django的情况有什么不同呢?

在处理多个线程时,您希望使用threadlocals,并希望将某些对象本地化到特定的线程,例如,每个线程有一个数据库连接。 在您的情况下,您希望将其更多地用作全局上下文(如果我理解正确的话),这可能是个坏主意。这将使你的应用程序更慢、更耦合、更难测试

为什么从请求传递它不值得?为什么不将其存储在会话或用户配置文件中

与Java的不同之处在于,它的web开发比Python/PERL/PHP/Ruby世界中的web开发更有状态,所以人们习惯于各种上下文和类似的东西。我不认为这是一个优势,但一开始似乎确实如此

另外,许多Java框架似乎经常使用threadlocals,那么它们的情况与Python/Django的情况有什么不同呢

CPython的解释器有一个全局解释器锁(GIL),这意味着解释器在任何给定时间只能执行一个Python线程。我不清楚Python解释器实现是否需要使用多个操作系统线程来实现这一点,尽管实际上CPython是这样做的

Java的主要锁定机制是通过对象的监视器锁。这是一种分散的方法,允许在多核和/或多处理器CPU上使用多个并发线程,但也会产生更复杂的同步问题供程序员处理

这些同步问题仅在“共享可变状态”时出现。如果状态是不可变的,或者像ThreadLocal一样,它不是共享的,那么Java程序员要解决的问题就不那么复杂了

CPython程序员仍然需要处理竞争条件的可能性,但是一些更深奥的Java问题(比如发布)可能是由解释器解决的


一个CPython程序员也可以选择Python可调用C或C++代码中的性能关键代码,而吉尔约束不适用。从技术上讲,Java程序员通过JNI也有类似的选择,但这在Java中被正确或错误地认为不如在Python中被接受。

我认为threadlocals没有任何问题-是的,它是一个全局变量,但除此之外,它是一个普通工具。我们使用它只是为了这个目的(将子域模型存储在全局上下文中,以满足来自中间件的当前请求),它工作得非常好


所以我说,使用合适的工具来完成这项工作,在这种情况下,threadlocals会使你的应用程序比在所有模型方法中传递子域模型更优雅(不提这一事实,它甚至不总是可能的——例如,当您重写django manager方法以限制子域的查询时,您无法传递任何额外的内容来获取_query_set——因此threadlocals是自然的也是唯一的答案).

我避免使用这种threadlocals,因为它引入了隐式的非本地耦合。我经常以各种非HTTP导向的方式使用模型(本地管理命令、数据导入/导出等)。如果我访问models.py中的一些threadlocals数据,现在我必须找到某种方法确保每当我使用我的模型时总是填充这些数据,这可能会变得非常糟糕

在我看来,更显式的代码更干净、更易于维护。如果模型方法需要子域才能运行,那么应该通过让方法接受该子域作为参数来说明这一事实


如果我完全无法找到将请求数据存储在threadlocals中的方法,我至少会在一个单独的模块中实现包装器方法,该模块访问threadlocals并使用所需的数据调用模型方法。这样,models.py就可以自含,并且可以在没有threadlocals耦合的情况下使用模型。

我发现使用ThreadLocal是在HTTP请求/响应环境(即任何webapp)中实现依赖项注入的一种很好的方法。您只需设置一个servlet过滤器,在接收请求时将所需的对象“注入”到线程中,在返回响应时将其“取消注入”

它是一个聪明人的DI,没有所有XML的丑陋,没有MB的Spring jar(更不用说它的学习曲线),没有所有神秘的重复@annotation废话,因为它没有单独注入许多对象实例与依赖项,它可能快得多,占用的内存更少

它工作得非常好,我们打开了exPOJO过滤器,它可以使用ThreadLocal注入Hibernate会话或JDO PersistenceManager:


为什么不将其存储在会话或用户配置文件中?
因为我需要从模型中访问它。
在你的情况下,你想更多地将其用作全局上下文
不是真的,我想在中间件中设置它,并使它可以在modles.py中访问,无需查看,每次都会显式地发送到models.py。卡尔:我同意这个观点ks局部性,但如果我必须在所有
.filter
调用中传递'subdoain'数据,这不是更糟的情况。这就是为什么我认为在这种情况下这是一个可以接受的折衷。在这种情况下,折衷可能是可以接受的;只有你可以打那个电话。你问“threadlocals有什么不好的地方”,所以我回答说