Python中C语言编程技巧的等效方法(while循环)

12 投票
3 回答
869 浏览
提问于 2025-04-16 20:00

在C语言中,我经常会做以下操作:

while ((c = getch()) != EOF) {
 /* do something with c */
}

在Python中,我没有找到类似的东西,因为我不能在被计算的表达式里面设置变量。结果我通常得把被计算的表达式写两遍!

c = sys.stdin.read(1)
while not (c == EOF):
 # Do something with c
 c = sys.stdin.read(1)

为了找到更好的方法,我发现了一种只需要设置一次被计算表达式的方法,但这看起来越来越复杂了...

while True:
 c = sys.stdin.read(1)
 if (c == EOF): break
 # do stuff with c

到目前为止,我在某些情况下采用了以下方法,但对于普通的while循环来说,这远不是最佳选择...:

class ConditionalFileObjectReader:
 def __init__(self,fobj, filterfunc):
  self.filterfunc = filterfunc
  self.fobj = fobj
 def __iter__(self):
  return self
 def next(self):
  c = self.fobj.read(1)
  if self.filterfunc(c): raise StopIteration
  return c

for c in ConditionalFileObjectReader(sys.stdin,lambda c: c == EOF):
 print c

我解决一个简单的编程问题的方法变得太复杂了... 有没有人能给我一些建议,教我怎么正确地做这件事?

3 个回答

3

你可以用更简单的代码来替代你的ConditionalFileObjectReader,因为看起来你最关心的是文件的结束标志(EOF),而不是其他什么条件:

def readbytes(file):
    while True:
        c = file.read(1)
        if c == '':
            return
        yield c

for c in readbytes(sys.stdin):
    print c

所以你还是用到了'while True ... break',这在Python中似乎是比较常用的循环方式[*],不过至少你只需要写一次就能解决“如何遍历一个类似文件的对象中的字节,而不需要逐行阻塞或缓冲”的问题,而且这个循环很简短,不会对'c'做什么操作——那是另外一个问题。

受到Wallacoloo的例子启发,使用iter,你可以做出比iter更通用的东西,类似于上面的代码:

def until(nextvalue, pred):
    while True:
        value = nextvalue()
        if pred(value):
            return
        yield value

for c in until(lambda: sys.stdin.read(1), lambda x: x == ''):
    print c

我不太确定我是否喜欢这个,但可能值得尝试一下。它试图解决一个更普遍的问题:“遍历某个函数的返回值,直到返回值满足某个条件”。

[*] 我敢说,这在Python中相当于其他语言中复杂循环语法的简化版吗?

18

在Python中,你通常会使用一个for循环:

for c in sys.stdin.read():
    # whatever

如果你不想一次性把所有输入都放到内存里,你也可以自己设置一个小一点的缓冲区来进行一些缓冲。

需要注意的是,常量EOF在Python中是不存在的。如果流中没有数据了,read()会直接返回一个空字符串。

14

我觉得你想做的事情是使用 iter 这个函数。

for c in iter(getch, EOF):
     #inner loop

iter 是一个非常灵活的函数。在这个例子中,你是在告诉它在每次循环的开始都要不断调用 getch(不带任何参数),直到 getch 返回一个特殊的值,叫做 EOF。

撰写回答