我经常发现自己从多个位置使用的方法返回一个布尔值,以便在一个地方包含该方法的所有逻辑。所有(内部)调用方法需要知道操作是否成功。
我正在使用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()
虽然它有效,但它的设计很糟糕。 我怎样才能改善这个?
答案 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函数。但是,我认为您的初始代码没有任何问题。