Python 为什么这种获取http客户端的方法会失败?

Python 为什么这种获取http客户端的方法会失败?,python,Python,上面的代码应该创建一个http客户机来向服务器发送请求。但是,当我使用下面的方法时,它给出了一个超时错误: def get_client(): with CoreClient(timeout=60000, memory='8G') as client: return client class RequestClient(object): def __init__(self, nlp): self.client = get_client(

上面的代码应该创建一个http客户机来向服务器发送请求。但是,当我使用下面的方法时,它给出了一个超时错误:

def get_client():
    with CoreClient(timeout=60000, memory='8G') as client:
        return client



class RequestClient(object):
      def __init__(self, nlp):
         self.client = get_client()
         ...

      def __call__(self, text):
         if text:
            with CoreNLPClient(timeout=60000, memory='8G') as client:
                doc = client.annotate(text, output_format='json')
         // OR 
            client = get_client()
            doc = client.annotate(text, output_format='json')

    ....
但是,如果我去掉了“get client()”方法,并直接按如下方式使用代码,它就可以正常工作:

client = get_client()
# submit the request to the server
doc = client.annotate(text, output_format='json')

为什么第一种获取客户端对象的方法失败了?

这是因为
with
语句导致的。发件人:

“with”语句是一种新的控制流结构,其基本 结构是:

with CoreClient(timeout=60000, memory='8G') as client:
  # submit the request to the server
  doc = client.annotate(text, output_format='json')
表达式将被计算,并且它将生成一个支持上下文管理协议的对象(即,has) 输入()和退出()方法

with块的执行完成后,对象的退出() 方法,即使该块引发异常,也可以 因此,运行清理代码

例如,在此代码段中:

with expression [as variable]:
  with-block 
执行此语句后,f中的文件对象将自动关闭,即使for循环在块的一部分引发异常。如果您尝试从此返回
f
,如下所示:

with open('/etc/passwd', 'r') as f:
  for line in f:
    print line
    ... more processing code ...
它将返回一个关闭的文件,这将禁止对其进行任何操作

def f():
  with open('/path/to/file') as f:
    return f
给出错误:

get_file = f()
get_file.readlines()
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
ValueError:对关闭的文件执行I/O操作

您的
CoreClient
对象也会发生类似的情况,它在执行
with
语句后关闭,因此返回一个关闭的对象,无法对其执行进一步的操作。

发生这种情况的原因是
with
语句。From:

“with”语句是一种新的控制流结构,其基本 结构是:

with CoreClient(timeout=60000, memory='8G') as client:
  # submit the request to the server
  doc = client.annotate(text, output_format='json')
表达式将被计算,并且它将生成一个支持上下文管理协议的对象(即,has) 输入()和退出
()方法

with块的执行完成后,对象的退出() 方法,即使该块引发异常,也可以 因此,运行清理代码

例如,在此代码段中:

with expression [as variable]:
  with-block 
执行此语句后,f中的文件对象将自动关闭,即使for循环在块的一部分引发异常。如果您尝试从此返回
f
,如下所示:

with open('/etc/passwd', 'r') as f:
  for line in f:
    print line
    ... more processing code ...
它将返回一个关闭的文件,这将禁止对其进行任何操作

def f():
  with open('/path/to/file') as f:
    return f
给出错误:

get_file = f()
get_file.readlines()
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
ValueError:对关闭的文件执行I/O操作

您的
CoreClient
对象也会发生类似的情况,它在执行
with
语句后关闭,因此返回一个关闭的对象,无法对其执行进一步的操作。

Jarvis,这是有道理的。我编辑了我的代码,并将其解释得更清楚。我想使用get\u client()的原因是是因为我想把它放在init方法中,而不是call方法中。如果它在call方法中,则必须为用户发出的每个请求创建它。对吗?是的,必须为发出的每个请求创建它。那么如何解决上述问题?如何将CoreClient的创建放在init函数中?如果我不使用statemen对于创建,我需要关闭它。如何关闭客户端?在您的
\uuuuu init\uuuuuuu
方法中,执行
self.client=CoreClient(timeout=60000,memory='8G')
不起作用?我想您可以定义
\uuu del\uuuuuu
(析构函数)包含关闭CoreClient对象的逻辑/代码,然后执行
del obj
,其中
obj
是完成后最后一个类
RequestClient
的实例,但这大部分是不必要的,因为Python会自动处理垃圾收集。它需要正确关闭,因为CoreClient会在内部创建一个post request。调用“annotate”方法后,需要将其关闭,类似于打开和关闭文件。Jarvis,这是有意义的。我编辑了我的代码并使其更清晰。我想使用get_client()的原因是因为我想把它放在init方法中,而不是call方法中。如果它在call方法中,则必须为用户发出的每个请求创建它。对吗?是的,必须为发出的每个请求创建它。那么如何解决上述问题?如何将CoreClient的创建放在init函数中?如果我不使用statemen对于创建,我需要关闭它。如何关闭客户端?在您的
\uuuuu init\uuuuuuu
方法中,执行
self.client=CoreClient(timeout=60000,memory='8G')
不起作用?我想您可以定义
\uuu del\uuuuuu
(析构函数)包含关闭CoreClient对象的逻辑/代码,然后执行
del obj
,其中
obj
是完成后最后一个类
RequestClient
的实例,但这大部分是不必要的,因为Python会自动处理垃圾收集。它需要正确关闭,因为CoreClient会在内部创建一个post请求。调用“annotate”方法后,需要将其关闭,类似于打开和关闭文件。