Python 3确定“或”操作的哪一部分是真的

时间:2016-07-18 15:46:09

标签: python

我有一个适合我目的的功能代码,但我不确定是否有更好的方法来满足我正在寻找的目标。这是我的代码:

def eitherOne(image1, image2):
    curIm1 = pyautogui.locateOnScreen(image1)
    curIm2 = pyautogui.locateOnScreen(image2)
    while curIm1 == None or curIm2 == None:
        curIm1 = pyautogui.locateOnScreen(image1)
        curIm2 = pyautogui.locateOnScreen(image2)
    if curIm1 != None:
        x, y = pyautogui.center(curIm1)
        pyautogui.click(x,y)
    if curIm2 != None:
        x, y = pyautogui.center(curIm2)
        pyautogui.click(x,y)

这样做的目的是寻找两个图像中的一个,然后点击最终为真的结果。是否有任何我可以使用的方法或函数可以确定“或”周围的哪些条件返回true而不运行后续的一组“if”操作?即使答案是“不,你需要if语句”,我也会很感激,所以我不会无缘无故地进行疯狂的追逐。

感谢您的时间!

2 个答案:

答案 0 :(得分:3)

我可能会做这样的事情。你创建一个无限循环,重复尝试一个图像,然后另一个,一旦其中一个图像成功就会中断。

def eitherOne(image1, image2):
    images = itertools.cycle([image1, image2])
    for img in images:
        curIm = pyautogui.locateOnScreen(img)
        if curIm is not None:
            break
    x, y = pyautogui.center(curIm)
    pyautogui.click(x, y)

如果您希望while循环到for循环,

def eitherOne(image1, image2):
    images = itertools.cycle([image1, image2])
    curIm = None
    while curIm is None:
        curIm = pyautogui.locateOnScreen(next(images))
    x, y = pyautogui.center(curIm)
    pyautogui.click(x, y)

或者,您可以使用itertools执行更多操作,以避免显式循环。

from itertools import cycle, imap, dropwhile

def eitherOne(image1, image2):
    curIm = next(dropwhile(lambda x: x is None, 
                           imap(pyautogui.locateOnScreen,
                                cycle([image1, image2]))))
    x, y = pyautogui.center(curIm)
    pyautogui.click(x, y)

(我有点意外,您无法使用None作为dropwhile的谓词,类似于filterfalse的方式。)

更新:实际上,由于filtermap已经在Python 3中返回了迭代器,因此无需使用dropwhileimap

def eitherOne(image1, image2):
    curIm = next(filter(None,
                        map(pyautogui.locateOnScreen,
                            cycle([image1, image2]))))
    x, y = pyautogui.center(curIm)
    pyautogui.click(x, y)

奖金内容!

要将功能方法推向极致,您可以在coconut中编写以下内容:

def eitherOne(image1, image2) = ([images1, images2] |>
                                 cycle |> 
                                 map$(pyautogui.locateOnScreen) |>
                                 filter$(None) |>
                                 next |>
                                 pyautogui.center |*>
                                 pyautogui.click)

答案 1 :(得分:1)

@ tobias_k对您的问题发表评论的v2.7示例。在Boolean Operation s中,返回True espresion的

class Img(object):
    def __init__(self, name):
        self.name = name
    def __bool__(self):
        return True

c1 = Img('c1')
c2 = None

current_image = c2 or c1
if current_image:
    print(current_image.name)
else:
    print('None')

在此示例中,c1已分配给current_image,因为它的评估结果为True并且其name已打印。