nb python 语法

在 bytesized32 的开源代码里面看到了一个玄学内容。

while True:
        try:

            stream = call_gpt(stream=True, model=model, messages=messages, **kwargs)
            pbar = tqdm(stream, unit="token", total=kwargs.get("max_tokens", 8*1024), leave=False)
            for chunk in pbar:
                time.sleep(0.01)  # Should help with Errno 104: Connection reset by peer https://stackoverflow.com/questions/383738/104-connection-reset-by-peer-socket-error-or-when-does-closing-a-socket-resu
                chunk_content = chunk.choices[0].delta.content

                if chunk_content:
                    response += chunk_content
                    pbar.set_postfix_str(f"...{response[-70:]!r}")

                    nb_tokens = count_tokens(chunk_content)
                    pbar.update(nb_tokens)
            else:
                pbar.close()
                break

        except (openai.APITimeoutError, openai.APIError, ChunkedEncodingError, ReadError, RemoteProtocolError) as e:
            if isinstance(e, openai.APIError):
                print("*****", e.type)
                if "An error occurred during streaming" not in e.message:
                    raise e

            # Append the response we received so far to messages.
            if len(messages) == 1:
                messages.append({"role": "assistant", "content": response})

            messages[-1] = {"role": "assistant", "content": response}
            print(e)

仔细看看 try except 的 try 最后面 else 和上面的 for 缩进一致,真的很玄学!

ChatGPT 给的解释是

在 Python 中,for 循环后面的 else 子句只有在循环没有被 break 语句中断的情况下才会执行。也就是说,如果 for 循环正常完成迭代而没有提前退出,else 子句就会执行。

所以说如果 for 循环中的内容因为 API 寄了,就不会进行 pbar.close(),然后在 except 里面把之前生成的内容作为 assistant 的回复 append 到 message 最后面。因为最外层是一个 while True,所以这样的实现可以有效避免 api 失效对整个 pipeline 的影响。

太酷啦!

其实我自己玩这个的时候也遇到了其它问题,比如 api 调用被 chunk 掉了,生成一个文字交互游戏代码,最后主函数写到 if __nam 就不写了。这个问题我觉得把 while True 改改就能解决,你怎么看!

posted @ 2024-08-02 10:23  yspm  阅读(107)  评论(0)    收藏  举报