Python 是否需要显式删除此对象?

Python 是否需要显式删除此对象?,python,Python,我面临的问题是“CoreClient”的创建,它创建了一个到服务器的http请求。“with…as client”引入的当前代码可以确保在“client.annotate”完成后超出范围时客户端被销毁。然而,问题是,必须为每个处理“文本”的请求创建对象“客户端”。为了避免这种情况,我最好在init方法中创建对象: class Tokenizer() def __init__(self): self.name = 'MyTokenizer' self.tokenizer = Lang

我面临的问题是“CoreClient”的创建,它创建了一个到服务器的http请求。“with…as client”引入的当前代码可以确保在“client.annotate”完成后超出范围时客户端被销毁。然而,问题是,必须为每个处理“文本”的请求创建对象“客户端”。为了避免这种情况,我最好在init方法中创建对象:

class Tokenizer()

def __init__(self):
   self.name = 'MyTokenizer'
   self.tokenizer = Language.create_tokenizer(nlp)

def __call__(self, text):
   if text:
      with CoreClient(timeout=60000) as client:
         doc = client.annotate(text, output_format='json')
   else:
      doc = Document("")

   ...
但是:

self.client = CoreClient(timeout=60000)
编辑:


为了更清楚,我添加了方法enter的实现。它似乎只是返回对象“self”。

在本例中,我不担心它,因为当引用计数变为零时,Python将处理它。而且,
del
实际上并不删除和删除对象。可能是,但可能不是
del
将减少对象的引用计数

以此为例:

def __enter__(self):
    self.start()
    return self

def start(self):
    if self.start_cmd:
        if self.be_quiet:
            # Issue #26: subprocess.DEVNULL isn't supported in python 2.7.
            stderr = open(os.devnull, 'w')
        else:
            stderr = self.stderr
        print(f"Starting server with command: {' '.join(self.start_cmd)}")
        self.server = subprocess.Popen(self.start_cmd,
                                       stderr=stderr,
                                       stdout=stderr)

这就是为什么我认为应该让Python来处理对象的破坏。Python跟踪对象引用计数,并知道何时不再需要它们。因此,让它为您处理这些事情。

您只需要创建一次
CoreClient的实例。
with
语句只确保在
with
语句体前后调用该实例的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
方法;您不需要每次都创建一个新实例

In [1]: class Test:
   ...:     def __del__(self):
   ...:         print('deleted')
   ...:

In [2]: t = Test()

In [3]: del t
deleted

In [4]: t = Test()

In [5]: t1 = t

In [6]: del t  # Nothing gets printed here because t1 still exists

In [7]: del t1  # reference count goes to 0 and now gets printed
deleted
每次将
CoreClient
实例用作上下文管理器时,
\uuuuuuuuuuuuuuuuuuuuuuuuuuuu>和
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu


当收集
标记器
实例时,将收集客户端。但是,除非您处于活动的
with
语句中,否则
CoreClient
实例不会执行任何操作。

为什么不让python的默认处理来处理这个问题呢?每当调用对象的析构函数时,对象都将被销毁。如果
del
对象,则只是删除对它的引用。如果仍然存在对该对象的其他引用,则该对象仍将保留。我认为当前创建该对象的方式很好,除非由于某种原因,
CoreClient
限制了它可以拥有的实例数。@Chrispresso IOW,
del
不会删除对象,要回答标题中的问题,几乎不需要使用
del
。对于您当前的代码,它就是。问题是,是否需要这样做?我的建议创建一次
CoreClient
实例,但调用
CoreClient.\uuu在该实例上输入\uuuuuu
,每次调用
标记器
实例。
\uu del\uuuu
也可能永远不会被调用,如果对象超出范围的原因是解释器正在关闭。我主要关心的是每个请求,创建CoreClint将花费太多时间,这是不好的。应该创建一次。嗨,切普纳:不幸的是,我刚刚测试并发现,由于调用函数中的语句“with self.client”,CoreClient被一次又一次地创建,这使得系统非常慢,因为系统的初始化需要时间。如果删除“with self.client”,则系统只初始化一次。但是在这种情况下,系统不会在完成http请求后关闭它,对吗?准确地说,
CoreClient
不是一次又一次地创建的;您创建了一次,但是
\uuuuu enter\uuuu
方法确实从头开始启动了一个新服务器。如果要跨调用使用同一台服务器,则必须重新实现
CoreClient
的工作方式。基本上,如何避免系统以当前代码形式多次初始化?根据您所展示的内容,似乎唯一的方法是重写
CoreClient
,除非有办法在
CoreClient中启动服务器。请将
self.start\u cmd
设置为
None
In [1]: class Test:
   ...:     def __del__(self):
   ...:         print('deleted')
   ...:

In [2]: t = Test()

In [3]: del t
deleted

In [4]: t = Test()

In [5]: t1 = t

In [6]: del t  # Nothing gets printed here because t1 still exists

In [7]: del t1  # reference count goes to 0 and now gets printed
deleted
class Tokenizer()

    def __init__(self):
       self.name = 'MyTokenizer'
       self.tokenizer = Language.create_tokenizer(nlp)
       self.client = CoreClient(timeout=60000)  # Create client here

    def __call__(self, text):
       if text:
          with self.client:
             doc = self.client.annotate(text, output_format='json')
       else:
          doc = Document("")