Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.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_Loops_Memory_Data Structures_Iteration - Fatal编程技术网

Python在迭代时禁用

Python在迭代时禁用,python,loops,memory,data-structures,iteration,Python,Loops,Memory,Data Structures,Iteration,因此,我正在创建一个基于存储和内存的数据结构。假设我有以下方法: def __store(self): #stores information into self.__memory list 现在我想做的是,如果这个函数是在一个循环中调用的,我希望只有在循环完成后才调用它 我的理由 此方法在许多其他方法中都会被调用,最重要的是\uuuuu setitem\uuuu,因此请查看以下代码: for i in xrange(100): class[i] = i + 5 现在,这将存

因此,我正在创建一个基于存储和内存的数据结构。假设我有以下方法:

def __store(self):
    #stores information into self.__memory list
现在我想做的是,如果这个函数是在一个循环中调用的,我希望只有在循环完成后才调用它

我的理由 此方法在许多其他方法中都会被调用,最重要的是
\uuuuu setitem\uuuu
,因此请查看以下代码:

for i in xrange(100):
    class[i] = i + 5
现在,这将存储信息直到循环完成(100次),但我只希望它在循环完成后存储信息

问题 本质上,如果程序中正在进行迭代,我只需要能够停止函数运行,然后在迭代完成后执行

我该怎么做?

额外信息 这个数据结构是一个字典,它有许多存储功能

我使用
\u store
存储的那种完整存储内存是为了撤销。循环中的任何内容都不需要撤消,因为在循环结束之前,用户不需要撤消任何内容

这个内存是基于控制的,所以迭代中的任何内容都不应该被存储,因为不需要实际的内存


这就是为什么我不希望在迭代期间存储,但是,如果需要存储的东西在迭代内部运行,我希望它在迭代内部完成后运行。

函数在循环内部的行为差异是个坏主意,请尝试使用
上下文管理器。这是一种更好的方法,更容易理解。

例如:

with sqlite3.connect(":memory:") as conn:
    # update will hold in transaction.
    for i in xrange(100):
        conn.execute("insert ....")

pass
# sqlite3 will commit now
同样地:

with a() as b:
    # data won't store
    for i in xrange(100):
        # don't store data
        b[i] = i + 5

pass
# data store while leave context
编辑1 ContextManager已进入,而退出方法将

class MemoryManager(object):
    def __init__(self):
        self.cache = {}
        self.buffer = False

    def __enter__(self):
        self.buffer = True

    def __store(self):
        # store data
        pass

    def __setitem__(self, key, value):
        self.cache[key] = value
        if not self.buffer:
            self.__store()

    def __exit__(self, exc_type, exc_value, traceback):
        self.__store()
        self.buffer = False
所以

m = MemoryManager()
with m as b:
    # __enter__ got called, set the manager to buffer mode
    # data won't store
    for i in xrange(100):
        # don't store data
        m[i] = i + 5    # in with block, so __store won't be called

pass
# __exit__ got called, __store automatically and leave buffer mode
m[0] = 10  # not in buffer mode, __store will be called 

好的,首先:让一个函数检测到它是从一个循环中被调用的,这有点荒谬。可以对这样的信息进行操作的函数几乎违反了Python方式的每一个方面,甚至像Perl这样的上下文敏感语言通常都避免内省调用方的环境,除非特别打算这样做。你需要这么多非标准的解释器

尽管如此,我认为“在循环中运行”并不是你真正想要函数的基础。根据您的描述,您希望就撤消状态而言,多步骤操作被视为单个操作,因为在用户看来,它将是单个更改,这是希望操作有时保存而不保存其他时间的完美逻辑原因。但在循环期间禁用撤消历史记录(因为您的应用程序可能在主循环中运行)或甚至仅在for循环期间禁用撤消历史记录(某些算法需要while循环,而您仍然希望在这些循环中禁用跟踪)并不能完全解决这一问题。另外,如果调用两个不同的函数影响同一个值,而对用户来说,这似乎是一个操作,那么情况又如何呢?您仍然只想保存对该值的一个更改


因此,我认为您真正想要的是在每次用户输入更改状态后保存状态,并默认撤消不知道的行为。

检测是否从外部迭代中调用它听起来是一个难题,但是,使用缓冲区在达到一定大小后进行刷新是解决类似问题的一种行之有效的方法——它不会阻止缓冲区在循环内刷新,但刷新频率会降低。您可以了解大量关于CPython的内部内容,并使用一些模糊的内省功能来分解字节码,并推断“调用堆栈上”的任何函数中是否正在进行循环,但这太疯狂了;-)没有直接的方法可以做到这一点。@kojiro我没有试图在循环中刷新它……我试图在循环完成之前不运行函数。这将保存所有以前的内存,但不会用不必要的内存使其过载。@TimPeters Inase对我来说很好,我只是需要一些指导,知道如何继续this@RyanSaxe,放弃吧,这是一条死胡同。据您所知,它是从(例如)一个
循环中的条件调用的,而True:
循环大约执行十亿次,其中条件只执行两次。也就是说,“在一个循环中”实际上是不相关的。多说你的实际问题,而不是所谓的“解决方案”。然后人们可以引导你采取明智的方法;-)等等,当你说“不存储数据”时,你的意思是该行不会执行吗?因为我需要在整个循环中更改字典,但我只需要在调用
\uuuu setitem\uuuu
时调用一个函数,我不希望在循环期间调用该函数。如果mak senseSee看到该示例,则仍将执行该行。但是上下文管理器使您能够检测它是否在with块内被调用。所以线在with块中的行为可能不同。好的,这似乎是最好的解决方案。要求人们编写一个带有块的代码是很烦人的,但这似乎是唯一的方法way@RyanSaxe你曾经写过编程语言吗?如果是这样,您是否为编码器提供了一种基于上下文禁用函数的方法,比如我的任何堆栈帧是否在循环或递归函数中?如果不是,我认为你的期望不仅不切实际,而且完全不公平。