Pythonic Django对象重用 [英] Pythonic Django object reuse

查看:112
本文介绍了Pythonic Django对象重用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在过去的几个星期里,我一直在大脑上,而我似乎无法理解它。我希望你们这里可以给我一些清晰度。



一小部分背景
我已经建立了一个API来帮助服务一个大型网站,像我们所有人一样,努力保持API尽可能高效。这种效率的一部分是不要在请求时重复创建一个包含自定义业务逻辑的对象(例如:一个服务类)。为了给出一些个人背景,我来自Java世界,所以我使用IoC或DI来帮助处理对象创建和注入到我的类中,以确保类不是根据每个请求一次被创建。



我读了
看了很多Python IoC和DI帖子,我对如何最好地创建一个给定的类,而不必担心服务器根据可能处理的请求量,太多的对象重载。



有人说IoC或DI真的不需要。但是,当我运行我的Django应用程序,我发现,除非我构造我想要的全局(文件顶部),以使views.py可以使用,而不是在每个视图类或def在views.py我运行更改创建多个类相同类型的,从我所理解的将导致服务器上的记忆膨胀。



那么,什么是正确的方法是pythonic来保持对象的建立一遍又一遍?我应该投资使用IoC / DI吗?我可以安全地依靠设置我的service.py文件来仅包含def而不是包含def的类吗?垃圾收集器是否有效,所以我甚至不必担心。



我有意没有在这篇文章中放置任何代码,因为这似乎是一般问题,但是如果有帮助,我可以提供几个代码示例。



感谢
从一个困惑的工程师想要尽可能的pythonic

解决方案

你来自所有需要的背景,作为一个类,我已经在Java中编程了Web应用程序而且,有时学习新东西比学习新东西更困难。



在Python / Django中,除非你需要很多,否则你不会做任何事情实例并需要保持状态。



对于一个很难的服务,有时你会注意到类似Java的网络应用程序,一些服务是单例,这是只是一个解决方法和一个相当大的反模式在Python



Pythonic



Python是足够灵活,不需要服务类,您只需要一个Python模块(例如, services.py )与一些函数,强调是一个功能,采取的东西,返回的东西,以完全无状态的方式。 / p>

 #services.py 
#这是一个模块,不保存任何状态,
#它可以读写数据库,做一些处理等,但不记得事情
def get_scores(student_id):
return Score.objects.filter(student = student_id)

#views.py
#接收HTTP请求
def view_scores(request,student_id):
scores = services.get_scores(student_id)
#eg使用模板中的分数查询返回HTML页面

注意如果您需要交换服务,你只需要交换一个Python模块(只是一个文件),所以Pythonistas几乎不用弄明显的接口和其他抽象。



内存



现在,每个django工作进程,你会有一个服务模块,即对于进入的所有请求,一次又一次地使用,当使用 Score queryset并且不再指向内存时,它将被清理。



我看到您的其他帖子,并且为每个请求实例化一个 ScoreService 对象,或将其保留在全局范围是不必要的,上面的例子在内存中有一个模块,而不需要我们对它的聪明。



如果你 需要在几个请求之间保持状态,保持它们在onli中 ScoreService 的实例将是一个坏主意,因为现在每个用户可能需要一个实例,这是不可行的(太多的在线对象保持上下文)。更不用说这个实例只能从同一个进程访问,除非你有一些共享机制。



在数据存储中保留状态



如果您希望保持状态中间请求,您将保持状态在数据存储中,当请求进入时,您点击服务模块再次从数据存储区获取上下文,拿起你离开的地方,做你的业务,返回你的HTTP响应,然后不用的东西就会收到垃圾。



重点在于保持无状态,任何给定的HTTP请求可以在任何给定的django进程处理,并且所有状态对象在返回响应并且对象超出范围之后被垃圾回收。



这可能不是我们可以提出的最快的请求/响应周期,但它可以像地狱一样可扩展



查看一些主要的Web应用程序Django



我建议你看看一些开源的Dja ngo项目,看看他们的组织方式,你会看到很多事情,你打破了你的大脑,Djangonauts只是不打扰。


I've been racking my brain on this for the last few weeks and I just can't seem to understand it. I'm hoping you folks here can give me some clarity.

A LITTLE BACKGROUND I've built an API to help serve a large website and like all of us, are trying to keep the API as efficient as possible. Part of this efficiency is to NOT create an object that contains custom business logic over and over again (Example: a service class) as requests are made. To give some personal background I come from the Java world so I'm use to using a IoC or DI to help handle object creation and injection into my classes to ensure classes are NOT created over and over on a per request basis.

WHAT I'VE READ While looking at many Python IoC and DI posts I've become rather confused on how to best approach creating a given class and not having to worry about the server getting overloaded with too many objects based on the amount of requests it may be handling.

Some people say an IoC or DI really isn't needed. But as I run my Django app I find that unless I construct the object I want globally (top of file) for views.py to use later rather than within each view class or def within views.py I run the change of creating multiple classes of the same type, which from what I understand would cause memory bloat on the server.

So what's the right way to be pythonic to keep objects from being built over and over? Should I invest in using an IoC / DI or not? Can I safely rely on setting up my service.py files to just contain def's instead of classes that contain def's? Is the garbage collector just THAT efficient so I don't even have to worry about it.

I've purposely not placed any code in this post since this seems like a general questions, but I can provide a few code examples if that helps.

Thanks From a confused engineer that wants to be as pythonic as possible

解决方案

You come from a background where everything needs to be a class, I've programmed web apps in Java too, and sometimes it's harder to unlearn old things than to learn new things, I understand.

In Python / Django you wouldn't make anything a class unless you need many instances and need to keep state.

For a service that's hardly the case, and sometimes you'll notice in Java-like web apps some services are made singletons, which is just a workaround and a rather big anti-pattern in Python

Pythonic

Python is flexible enough so that a "services class" isn't required, you'd just have a Python module (e.g. services.py) with a number of functions, emphasis on being a function that takes in something, returns something, in a completely stateless fashion.

# services.py
# this is a module, doesn't keep any state within,
# it may read and write to the DB, do some processing etc but doesn't remember things
def get_scores(student_id):
    return Score.objects.filter(student=student_id)

# views.py
# receives HTTP requests 
def view_scores(request, student_id):
    scores = services.get_scores(student_id)
    # e.g. use the scores queryset in a template return HTML page

Notice how if you need to swap out the service, you'll just be swapping out a single Python module (just a file really), so Pythonistas hardly bother with explicit interfaces and other abstractions.

Memory

Now per each "django worker process", you'd have that one services module, that is used over and over for all requests that come in, and when the Score queryset is used and no longer pointed at in memory, it'll be cleaned up.

I saw your other post, and well, instantiating a ScoreService object for each request, or keeping an instance of it in the global scope is just unnecessary, the above example does the job with one module in memory, and doesn't need us to be smart about it.

And if you did need to keep state in-between several requests, keeping them in online instances of ScoreService would be a bad idea anyway because now every user might need one instance, that's not viable (too many online objects keeping context). Not to mention that instance is only accessible from the same process unless you have some sharing mechanisms in place.

Keep state in a datastore

In case you want to keep state in-between requests, you'd keep the state in a datastore, and when the request comes in, you hit the services module again to get the context back from the datastore, pick up where you left it and do your business, return your HTTP response, then unused things will get garbage collected.

The emphasis being on keeping things stateless, where any given HTTP request can be processed on any given django process, and all state objects are garbage collected after the response is returned and objects go out of scope.

This may not be the fastest request/response cycle we can pull, but it's scalable as hell

Look at some major web apps written in Django

I suggest you look at some open source Django projects and look at how they're organized, you'll see a lot of the things you're busting your brains with, Djangonauts just don't bother with.

这篇关于Pythonic Django对象重用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆