简体   繁体   English

为什么以下循环不会中断-Python?

[英]Why does the following loop not break - Python?

I am trying to print the results of cmd ping google.com , which should output 9 lines in total then stop. 我正在尝试打印cmd ping google.com的结果,该结果应总共输出9行然后停止。

Pinging google.com [216.58.208.46] with 32 bytes of data:
Reply from 216.58.208.46: bytes=32 time=27ms TTL=55
Reply from 216.58.208.46: bytes=32 time=27ms TTL=55
Reply from 216.58.208.46: bytes=32 time=27ms TTL=55
Reply from 216.58.208.46: bytes=32 time=28ms TTL=55

Ping statistics for 216.58.208.46:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 27ms, Maximum = 28ms, Average = 27ms

After running my script below 在下面运行我的脚本后

import subprocess
from subprocess import Popen, PIPE

proc = subprocess.Popen(['ping','www.google.com'],stdout=subprocess.PIPE)
while True:
  line = proc.stdout.readline()
  if line != '':
    print("line:", line)
  else:
    break

I see the dynamically printed cmd results line by like, however after the last line is printed, my loop carries on printing forever, like the following 我看到了动态打印的cmd结果行,例如,但是在最后一行打印完之后,我的循环将永远进行打印,如下所示

line: b'Pinging www.google.com [216.58.208.36] with 32 bytes of data:\r\n'
line: b'Reply from 216.58.208.36: bytes=32 time=27ms TTL=56\r\n'
line: b'Reply from 216.58.208.36: bytes=32 time=26ms TTL=56\r\n'
line: b'Reply from 216.58.208.36: bytes=32 time=27ms TTL=56\r\n'
line: b'Reply from 216.58.208.36: bytes=32 time=26ms TTL=56\r\n'
line: b'\r\n'
line: b'Ping statistics for 216.58.208.36:\r\n'
line: b'    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),\r\n'
line: b'Approximate round trip times in milli-seconds:\r\n'
line: b'    Minimum = 26ms, Maximum = 27ms, Average = 26ms\r\n'
line: b''
line: b''
line: b''
line: b''
line: b''
line: b''
line: b''
line: b''
line: b''
...

I am wondering if my loop is carrying on because of this mysteriuos b character, but where is this b character coming from after line: ? 我想知道我的循环是否由于这个mysteriuos b字符而继续进行,但是此b字符从下一行来哪里?

modifying 修改

    print("line:", line)

to

    print("line:", line[1:])

returns 退货

line: b'inging www.google.com [216.58.208.36] with 32 bytes of data:\r\n'
line: b'eply from 216.58.208.36: bytes=32 time=28ms TTL=56\r\n'
line: b'eply from 216.58.208.36: bytes=32 time=29ms TTL=56\r\n'
line: b'eply from 216.58.208.36: bytes=32 time=27ms TTL=56\r\n'

not removing the b character. 不删除b字符。

How can I fix this? 我怎样才能解决这个问题?

replace 更换

if line != '':

with

if line:

After the output is finished it doesn't produce a '' . 输出完成后,不会产生'' It is therefore easier to check whether an output equates to True or False . 因此,更容易检查输出是否等于TrueFalse

This works well in Python as empty strings, lists, tuples, dictionaries etc, as well as the number 0 and the value None , all equate to False when used in the above manner. 在Python中,它可以很好地用作空字符串,列表,元组,字典等,以及数字0和值None ,以上述方式使用时都等于False

In regards to the b character, that denotes that what you are receiving is a byte string, instead of a normal string. 关于b字符,表示您收到的是字节字符串,而不是普通字符串。 You can't remove the b using slicing in the same way you can't remove the [] brackets from a list using slicing. 您无法像使用切片一样从列表中删除[]括号一样使用切片来删除b

To get rid of the b you'll need to decode your string. 要摆脱b,您需要decode字符串进行decode

As you use print() and output begins with b , I assume you are using a Python 3.x. 当您使用print()且输出以b开头时,我假设您使用的是Python3.x。 In Python 3.x, a string is made of unicode chars , whereas bytes and bytearray s are made of bytes (8 bits). 在Python 3.x中,字符串由unichar char组成,而bytesbytearray由字节(8位)组成。 The initial b just says that line is in fact a bytes object. 最初的b仅表示该line实际上是一个bytes对象。

Your test should then be either if str(line) != '': or if line != b'': , because '' == b'' returns False because they are objects of different classes. 然后您的测试应该是if str(line) != '':还是if line != b'': '' == b''因为'' == b''返回False因为它们是不同类的对象。

Since this is Python, this loop does what you want and is more readable: 由于这是Python,因此此循环可以满足您的需求,并且更具可读性:

for line in proc.stdout:
    print(line)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM