Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.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_Nonblocking - Fatal编程技术网

Python 继续执行时从函数返回

Python 继续执行时从函数返回,python,django,nonblocking,Python,Django,Nonblocking,我正在开发一个Django应用程序,我想在第一次创建对象时填充模型中的几个字段。目前,我可以在我的模型的save()例程中这样做: def save(self, *args, **kwargs): file = fileinfo.getfileinfo(self.file_path) if not self.file_size: self.file_size = file.FileSize if not self.file_inode: s

我正在开发一个Django应用程序,我想在第一次创建对象时填充模型中的几个字段。目前,我可以在我的模型的
save()
例程中这样做:

def save(self, *args, **kwargs):
    file = fileinfo.getfileinfo(self.file_path)
    if not self.file_size:
        self.file_size = file.FileSize
    if not self.file_inode:
        self.file_inode = file.FileInode
    if not self.duration:
        self.duration = file.Duration
    if not self.frame_width:
        self.frame_width = file.ImageWidth
    if not self.frame_height:
        self.frame_height = file.ImageHeight
    if not self.frame_rate:
        self.frame_rate = file.VideoFrameRate
    super(SourceVideo, self).save(*args, **kwargs)
我在一个名为
fileinfo
的单独模块中创建了一个名为
getfileinfo
的函数。这是我函数的一部分:

def getfileinfo(source):
    fstats = os.stat(source)
    info = dict({
        u'FileSize': fstats.st_size,
        u'FileInode': fstats.st_ino
    })
    output = subprocess.Popen(
        [exiftool, '-json', source], stdout=subprocess.PIPE)
    info.update(
        json.loads(output.communicate()[0], parse_float=decimal.Decimal)[0])
    return DotDict(info)
尽管所有这些都有效,但如果检索过程因某种原因延迟,我希望避免阻塞保存过程。在对象创建时不需要这些信息,可以在此后不久填充这些信息。我的想法是,我会改变我的函数,接受有问题的文件路径以及对象的主键。有了这些信息,我可以获得这些信息,然后作为一个单独的操作更新我的对象条目

比如:

def save(self, *args, **kwargs):
    fileinfo.getfileinfo(self.file_path, self.id)
    super(SourceVideo, self).save(*args, **kwargs)
我想要帮助的是如何在函数实际完成之前从函数返回。我想调用函数,然后让它不返回任何内容,只要调用正确。但是,该函数应继续运行,并在完成后更新其末端的对象。如果我需要澄清什么,请告诉我。还有,这件事是工作在做吗


谢谢

我不知道您的具体案例是否会像这样工作,但我可能会创建一个新线程,指向您的
super.save
,如下所示:

import threading

#other code here
def save(self, *args, **kwargs):
    fileinfo.getfileinfo(self.file_path, self.id)
    my_thread = threading.Thread(target=super(SourceVideo, self).save,
            args=args, kwargs=kwargs)
    my_thread.start()
这样,
save
将在后台运行,同时执行其余代码


但是,只有当执行过程中,
save
没有阻止其他地方可能需要的任何数据时,这才有效。

听起来您真正想要做的是返回一个表示仍需要完成的工作的对象,然后将完成处理程序或观察者附加到该返回的对象上,它使用结果填充模型对象,然后调用super.save()


需要注意的是,我不确定这种方法是否适合Django应用程序模型。

在这种情况下,最好的选择是使用

这使您能够创建将在后台执行的任务,而不会阻止当前请求


在您的情况下,您可以.SAVER(),创建更新字段的任务,将其推送到您的芹菜队列,然后返回对用户的期望响应。

< P>我不知道您的要求,但是如果这个操作在Access上接受不可接受的时间,但在Access上接受的话,我会考虑处理“代码>文件化< /代码>,
持续时间
视频帧率
等,作为模型的延迟加载属性,假设较长的初始加载时间是较短保存时间的一个合理折衷

有很多方法可以做到这一点:例如,可以缓存第一次访问的帧速率。如果您希望将其存储在数据库中,则可以通过a访问帧速率,并在第一次访问时计算它(以及其他值,如果合适),然后将它们存储在数据库中。从理论上讲,这些是文件本身的属性,因此您的界面不应允许更改它们,从而使它们与它们引用的文件不同步。按照这些思路,我可能会这样做:

class MyMediaFile(models.Model):
    file = models.FileField()
    _file_size = models.IntegerField(null=True, editable=False)
    _duration = models.IntegerField(null=True, editable=False)
    <... etc ...>

    @property
    def file_size(self):
        if self._file_size:
            return self._file_size
        else:
            self.populate_file_info(self)
            return self._file_size

    def populate_file_info(self):
        < ... do your thing here ... >
        self._file_size = my_calcuated_file_size
        < ... etc ... >
类MyMediaFile(models.Model):
file=models.FileField()
_文件大小=models.IntegerField(null=True,editable=False)
_duration=models.IntegerField(null=True,editable=False)
@财产
def文件大小(自身):
如果是自文件大小:
返回自我。\u文件\u大小
其他:
self.populate\u file\u info(self)
返回自我。\u文件\u大小
def填充文件信息(自身):
< ... 在这里做你的事…>
self.\u file\u size=我的\u计算的\u文件大小
< ... 等等…>

每个
属性
的逻辑可以很容易地划分为一个通用的延迟加载
@property
,因此不需要为每个属性重复样板文件。

我可以在另一端使用相同的技术吗?比如说,使用
线程生成一个新线程,然后在我的另一个函数的末尾返回一些东西?如果你想执行很多这样的线程,那么最好创建两个
队列
对象,一个用于发送到线程,一个用于从线程返回。然后,您可以通过类似
result=return\u queue.get(timeout=60)#60秒
的查询返回结果。这有帮助吗?我过去曾简单地看了一下芹菜,现在又看了一眼。然而,我想做的似乎应该是简单的。了解如何使用标准库或语言本身的各个方面来实现这一点会更加有益。另外,我想暂时保持对其他软件包的低依赖性。