print
함수는 우리 일상생활에서 가장 흔히 사용되는 함수임에는 틀림이 없습니다. 출력 형식을 지정하든, 디버깅을 위해 중간 변수를 출력하든, 에 나오는 함수는 거의 없습니다. print
가 작업을 처리할 수 없습니다. print
函数是我们日常最常用的函数,无论是格式化输出还是打印中间变量进行调试,几乎没有 print
接不了的活儿。
但是上一次阿酱就差点被 print
给坑了。
最初是想要为自己的一个命令行小工具增加一个进度显示功能,于是用了 threading
模块来实现多线程,一个线程用于执行实际的逻辑,另一个线程用于打印当前进度。
根据我们
多年 使用命令行的经验,一般打印进度都是在行内打印,而Python的 print
则会默认在结尾打印一个换行符,这就十分不美了。
不过好在, print
也提供了接口来改变打印的末尾字符,通过指定 print
的 end
参数,即可改变 print
的打印结果。
所以我就哼哧哼哧地开干了,把打印进度的 print("#")
调用改为 print("#", end="")
。
类似这样:
哪成想,这么一改却出了大问题:进度没法实时打印了。
也就是说,本来应该在程序执行期间,挨个打印出来的 #
号不再是听话的、可爱的 #
号了,而是在整个程序执行完成之后一次性输出到控制台中。
它长大了, 也变丑了 。
那我要你有何用?
一开始阿酱以为是多线程出了问题,傻乎乎地到处找资料来“佐证”自己的各种猜测——事后想来实在太傻了,以至于现在说起还是会哈哈哈
这件事给我们的教训就是: 千万不要自以为是,而应踏踏实实地解决问题,虚心对待每个细节 。
实际上,之所以我们看不到实时的输出,就是因为我们改变了 print
的结尾字符。
为了尽量减少I/O操作,Python存在一个这样的机制:尽量将输出字符缓存起来,当遇到字符串结束、换行符或强制刷新缓冲区时,才会一次性将缓冲区的内容输出到相应的流中。
——而我们改掉的地方,就是把 print
默认的换行符去掉了,所以原本每一个 print
都会触发一次缓冲区刷新,变成了现在一直触发不了缓冲区刷新,直到程序结束触发一次。
好嘛,知道了啥问题,我们又吭哧吭哧找资料,听说 sys.stdout.flush
可以强制触发标准输出缓冲区的刷新,于是在 print
后面,紧跟着又加上了 sys.stdout.flush()
인쇄
에 속을 뻔했습니다.
스레딩 멀티스레딩을 구현하는 모듈로, 하나의 스레드는 실제 로직을 실행하는 데 사용되고 다른 스레드는 현재 진행 상황을 인쇄하는 데 사용됩니다. <figure><img class="lazyload" src="https://img.php.cn/upload/article/000/000/052/e81d361fe9c2aab616d404b5cdf741d3-12.png" data- style="max-width:90%" data- style="max-width:90%" alt="사람들은 Python을 사용할 때 얼마나 많은 함정을 겪었습니까? 위험을 피하세요!" ><img class="lazyload" src="https://img.php.cn/upload/article/000/000/052/00378eb73c929c1c9646673ec2efcc73-0.png" data- style="max-width:90%" data-height=" 600" alt="사람들은 Python을 사용할 때 얼마나 많은 함정을 겪었습니까? 위험을 피하세요!" ><figcaption></figcaption></figure><figure><figcaption>클릭하고 드래그하여 이동하세요</figcaption></figure><p>우리의 </p>🎜년 동안의 명령줄 사용 경험에 따르면 일반적으로 인쇄 진행 상황은 인라인으로 인쇄되며 Python의 <code>인쇄
🎜 🎜 기본적으로 끝에 개행 문자가 인쇄되는데 이는 매우 보기 흉합니다. 🎜🎜다행히 print
는 인쇄의 마지막 문자를 변경할 수 있는 인터페이스도 제공합니다. print
의 end
매개변수를 지정하면 변경할 수 있습니다. 인쇄의 인쇄 결과입니다. 🎜🎜그래서 작업을 시작하고 진행 상황을 print("#", end="") code>로 인쇄하도록 print("#")
호출을 변경했습니다. 🎜🎜이와 유사: 🎜🎜🎜🎜🎜🎜🎜클릭하고 드래그하여 이동하세요🎜🎜🎜그런 것 같지는 않지만 이번 변경에는 큰 문제가 있습니다. 진행 상황을 실시간으로 인쇄할 수 없다는 점입니다. 🎜🎜🎜🎜🎜🎜🎜클릭해서 드래그하면 이동🎜🎜🎜즉, 프로그램 실행 중 하나씩 출력되어야 했던 #
숫자가 더 이상 순종적이지 않게 된 것입니다. 귀엽고 #
이지만 전체 프로그램이 실행된 후 한꺼번에 콘솔에 출력됩니다. 🎜🎜성장했고 못생기기도 했습니다. 🎜🎜🎜🎜🎜🎜🎜클릭하고 드래그하여 이동하세요🎜🎜🎜그럼 나한테 네가 필요한 게 뭐야? 🎜🎜🎜🎜🎜🎜🎜클릭하여 드래그하여 이동하세요🎜🎜문제가 무엇인가요?
🎜처음에 Ajiang은 멀티스레딩에 문제가 있다고 생각하여 자신의 다양한 추측을 "지원"하기 위해 어리석게도 여기저기에서 정보를 찾았습니다. 나중에 생각해보면 너무 어리석어서 이야기할 때 여전히 웃습니다. 이제🎜 🎜🎜🎜🎜🎜🎜클릭하고 드래그하여 이동하세요🎜🎜🎜이 사건이 우리에게 주는 교훈은 절대 독선적이지 말고, 현실적으로 문제를 해결하고 모든 세부 사항을 겸손하게 대하라는 것입니다. . 🎜🎜사실 실시간 출력을 볼 수 없는 이유는 print
의 끝 문자를 변경했기 때문입니다. 🎜🎜I/O 작업을 최소화하기 위해 Python에는 문자열 끝, 개행 문자 또는 버퍼가 강제로 새로 고쳐질 때 출력 문자를 최대한 캐시하는 메커니즘이 있습니다. 해당 스트림으로 즉시 출력됩니다. 🎜🎜——우리가 변경한 것은 print
의 기본 개행 문자를 제거하는 것입니다. 따라서 원래 모든 print
는 버퍼 새로 고침을 트리거했지만 이제는 버퍼 새로 고침을 트리거할 수 없습니다. 프로그램이 끝날 때까지. 🎜🎜자, 이제 문제가 무엇인지 알았으니 다시 정보를 찾기 시작했습니다. sys.stdout.flush
가 강제로 표준 출력 버퍼 플러시를 트리거할 수 있다고 들었습니다. >print
그 후 sys.stdout.flush()
가 즉시 추가되었습니다. 🎜🎜에? 정말 좋은가요? 🎜🎜🎜🎜🎜🎜🎜🎜클릭하고 드래그하여 이동하세요🎜🎜🎜이것들은 모두 지식 포인트입니다. 적어두고 시험에 응시하세요🎜 print
에 대한 공식 문서를 확인해 보세요. 프로토타입은 다음과 같습니다: print
的官方文档,其原型为:
根据其下的描述,Python中 print
的输出是否进行缓冲,取决于两个参数: file
和 flush
。
file
的类型有的需要缓冲,比如 sys.stdout
;而有的则不需要缓冲,比如 sys.stderr
。
对于 flush
参数,当其值为 False
(默认)时,是否缓冲依赖 file
;而当其值为 True
时,则会强制刷新缓冲区。
我们把示例调用中的 print
调用修改一下:
同样可以实现进度的实时打印。
此外,还有一种方法,在调用程序时增加一个 -u
print
호출을 수정해 보겠습니다.
클릭하여 모바일로 드래그하세요또한, 프로그램을 호출할 때
-u
옵션을 추가하는 방법이 있으며, 이를 통해 버퍼를 실시간으로 새로 고칠 수도 있습니다. 🎜🎜🎜🎜🎜🎜🎜🎜클릭하여 드래그 to move🎜 🎜🎜🎜🎜🎜🎜🎜🎜클릭하고 드래그하여 이동🎜🎜🎜물론 이 방법은 권장되지 않습니다. 결국 프로그램 사용자를 위한 사전 설정이 불가능하기 때문입니다. 🎜🎜요약🎜🎜이 글은 Ajiang의 함정에 대한 기록입니다. Python에서 소수의 사람들이 직면하게 될 이상한 문제를 기록합니다. 🎜🎜일반적으로, 진정한 Python 프로그래머가 되려면 단순히 기본 구문과 몇 가지 요령을 익히는 것만으로는 충분하지 않습니다. Python 자체에 대한 어느 정도 이해가 필요합니다. 🎜🎜결국, 자신의 검에 익숙하지 않은 검객이 어떻게 세상을 헤쳐 나갈 수 있겠습니까? 🎜🎜🎜관련 무료 학습 권장사항: 🎜python 비디오 튜토리얼🎜🎜🎜위 내용은 사람들은 Python을 사용할 때 얼마나 많은 함정을 겪었습니까? 위험을 피하세요!의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!