如何改进这个布尔函数?

时间:2013-05-16 20:48:02

标签: python optimization

我经常发现自己从多个位置使用的方法返回一个布尔值,以便在一个地方包含该方法的所有逻辑。所有(内部)调用方法需要知道操作是否成功。

我正在使用Python,但问题并不一定是针对该语言的。我能想到的只有两个选择 提出异常,虽然情况并非例外,但请记住在函数调用的每个地方捕获异常 我正在做一个布尔值。

这是一个非常简单的例子,展示了我所说的内容。

import os

class DoSomething(object):

    def remove_file(self, filename):

        try:
            os.remove(filename)
        except OSError:
            return False

        return True

    def process_file(self, filename):

        do_something()

        if remove_file(filename):
            do_something_else()

虽然它有效,但它的设计很糟糕。 我怎样才能改善这个?

5 个答案:

答案 0 :(得分:3)

在@Joran Beasley的回答的基础上,我将其他东西放在其他区块中:

class DoSomething(object):

    def process_file(self, filename):

        do_something()

        try:
            os.remove(filename)
        except OSError:
            return False
        else:
            do_something_else()

答案 1 :(得分:3)

我不确定我理解你在这里要解决的问题,但这个评论似乎很有启发性:

  

我可以在尝试删除之前使用os.path.exists(filename),但不能保证文件在此期间不会被锁定,我仍然需要确定删除是否成功。

同时也无法保证文件不会被删除,或同时替换为不同的文件等。所以,你是对的,你不应该使用os.path.exists

但这里的问题是什么?试着删除它。如果文件不存在,则会出现异常。如果文件被锁定或无法删除,则会出现异常。无论哪种方式,删除都失败了。

如果问题是将一个失败原因与其他失败原因区分开来,那么你可以特别处理它,这很容易:

try:
    os.remove(filename)
except FileNotFoundError:
    print("Oops, {} doesn't exist".format(filename))
except OSError as e:
    print('Got {} trying to delete {}'.format(e, filename))
else:
    do_something_else()

如果您使用的是Python的早期版本而不是3.3,那么您没有FileNotFoundError,所以......它不那么漂亮,但是同样的想法:

try:
    os.remove(filename)
except OSError as e:
    if e.errno == errno.ENOENT
        print("Oops, {} doesn't exist".format(filename))
    else:
        print('Got {} trying to delete {}'.format(e, filename))
else:
    do_something_else()

答案 2 :(得分:2)

我能想到OP是糟糕设计的唯一原因是:通常在python中有两种思想流派在你跳跃之前看看更容易提出许可而不是宽恕< / strong>,但在您的代码中,您正在做两件事。通常你只选择一个或另一个

class DoSomething(object):

    def process_file(self, filename):

        do_something()

        try:
            os.remove(filename)
        except OSError:
            return False
        else:
            do_something_else()

非常清洁imho

答案 3 :(得分:2)

在这种情况下,允许(或引发)异常是可以的。整个想法是流量控制可以在理解“更大的图景”的水平上处理,并且可能能够对其做些什么。内部部分在路上愉快地携带,而不必检查布尔标志。

例如,如果删除文件失败 - 这是灾难性的 - 可能是你的内部函数不知道,所以它不应该掩盖堆栈跟踪。更高,它可能能够重试或只是决定实际上它不是那么糟糕,让我们继续。强制异常返回意味着信息丢失并要求用户记住实际检查返回结果 - 此外,某些函数可能具有真正的布尔返回结果,因此识别这些的唯一方法是通过处理异常。

答案 4 :(得分:0)

好吧,我想如果你真的想删除“boolean”,你可以使用像lambda这样的

def remove_file(self, filename, success):
    try:
        os.remove(filename)
    except OSError:
        //error stuff
    else:
        success()

def process_file(self, filename):
    do_something()
    remove_filename(filename, lambda: do_something_else())

您可以将所需的参数传递给函数,然后将其包装在lambda中,因此只有在删除填充成功后才会执行success函数。但是,我认为您的初始代码没有任何问题。