除非我重置内核,否则对象不会在 Jupyter Notebook 中“重置”

Zac*_*ach 1 python class ipython python-3.x jupyter-notebook

这是一个奇怪的问题,我不完全确定如何恰当地提出问题,但我会尽力而为。

我有一个自定义类,它基本上是一个 API 的包装器,它在每次调用时使用新数据更新 SQLite 数据库(我无法将其添加到问题中,因为它是庞大且私密的)。

奇怪的是,似乎有些信息正在被缓存(我认为这是不可能的,但这是它让我想起的唯一一件事,比如当你在 web dev 中进行编辑但他们没有更新时)因为它首先起作用时间,但是当我尝试重新初始化对象并再次运行它时,它不会向数据库添加任何新数据(当我知道有新数据要添加时)。

我知道代码有效,因为如果我重新启动内核并再次运行它,它更新没有问题。

我尝试删除对象 ( del InitializedClass)、重新初始化并使用不同的值进行初始化,但似乎没有任何效果。除非重新启动内核,否则它不会更新数据库。

有没有人遇到过这样的问题?如果这还不够,我很乐意提供更多信息,但我不知道如何描述它。

谢谢!!


编辑

下面的伪代码基本上就是正在发生的事情

from something import SomeClass    

while True:

    obj = SomeClass() #      <---------  How can I "reset" this on each loop?

    obj.get_new_data_from_api()
    obj.update_raw_db()
    obj.process_raw_data()
    obj.update_processed_db()

    # i tried different combinations of deleting the object
    del obj
    del SomeClass
    from something import SomeClass
Run Code Online (Sandbox Code Playgroud)

编辑2:

所以正如大家所提到的,这是类本身的问题,但我仍然不明白为什么会发生错误。基本上,end当我将datetime.now()函数调用作为默认 kwarg(即使在删除类并创建新实例之后,这并没有)更新)。该问题如下图所示:

class SomeBrokenClass():

    def __init__(self):    
        pass

    def get_endpoint(self, start, end):
        return 'https://some.api.com?start_date=%s&end_date=%s' % (start, end)

    # THE PROBLEM WAS WITH THIS METHOD ( .get_data() ):
    # When re-initializing the class, the `end` argument
    # was not being updated for some reason. Even if I completely
    # delete the instance of the class, the end time would not update.

    def get_data(self, start, end = int(datetime.now().timestamp() * 1000)):
        return pd.read_json(self.get_endpoint(start, end))

    def get_new_data_from_api(self):
        start_date = self.get_start_date()
        df = self.get_data(start_date)
        return df


class SomeWorkingClass():

    def __init__(self):    
        pass

    def get_endpoint(self, start, end):
        return 'https://some.api.com?start_date=%s&end_date=%s' % (start, end)

    def get_data(self, start, end):
        return pd.read_json(self.get_endpoint(start, end))

    def get_new_data_from_api(self):
        start_date = self.get_start_date()
        end_date = int(datetime.now().timestamp() * 1000) # BUT THIS WORKS FINE
        df = self.get_data(start_date, end_date)
        return df
Run Code Online (Sandbox Code Playgroud)

Blc*_*ght 5

您的问题与您的方法之一中参数的默认值有关:

def get_data(self, start, end = int(datetime.now().timestamp() * 1000)):
    ...
Run Code Online (Sandbox Code Playgroud)

每次调用函数时都不会重新计算默认值。相反,作为默认值给出的表达式仅在定义方法时计算一次,并且该值被存储以用作所有后续调用的默认值。这在这里不起作用,因为datetime.now它只在加载模块时计算,而不是每次调用函数时。

解决此问题的常用方法是将哨兵值设置None为默认值,然后如果找到哨兵,则在函数内部计算适当的值:

def get_data(self, start, end=None):
    if end is None:
        end = int(datetime.now().timestamp() * 1000)
    ...
Run Code Online (Sandbox Code Playgroud)