为平台定义具有变体的功能的最正确方法

时间:2019-04-08 01:38:57

标签: python python-3.x correctness

今天我碰到了this answer,它在确定系统平台后定义了函数。

我一直认为(或更确切地说,从来没有真正考虑过)确定跨平台功能正确行为的条件应该放在定义的 之内。

import subprocess
import sys

def show_file(path):
    if sys.platform == "darwin":
        subprocess.check_call(["open", "--", path])
    elif sys.platform == "linux":
        subprocess.check_call(["xdg-open", "--", path])
    elif sys.platform == "win32":
        subprocess.check_call(["explorer", "/select", path])

我很好奇,用 @Dietrich Epp 的方式来做是否更有效率?

if sys.platform == "darwin":
    def show_file(path):
        subprocess.check_call(["open", "--", path])
elif sys.platform == "linux":
    def show_file(path):
        subprocess.check_call(["xdg-open", "--", path])
elif sys.platform == "win32":
    def show_file(path):
        subprocess.check_call(["explorer", "/select", path])

我不知道上面的任何一个片段是否都能工作,但是无论如何这都不是问题的一部分。

3 个答案:

答案 0 :(得分:2)

第一个版本在每次调用show_file时执行平台检查;第二个没有。不过,它可能不会使它变慢得足够慢。

答案 1 :(得分:2)

show_file()函数定义放在条件中的一个后果是,尝试在不受支持的平台上使用此函数将引发NameError。将条件放在show_file函数中将导致它默默地失败,除非您在最后的raise块中还包含一个else

取决于您,哪个更好。我个人更希望在不受支持的平台上出现明显的错误,但是我想为清楚起见,最好将其作为最终的else条件来处理,这样异常的原因就很清楚了。

这两种情况之间的效率可以忽略不计。我会更关注代码的可读性和异常处理。

答案 2 :(得分:0)

“最佳方法”可能取决于您的优先级。

一种类似的方法可能是优先考虑可读性,并准备代码以提取抽象。可能就是这样,如果由于不支持平台而无法正确分配功能,则会引发异常。

import subprocess
import sys


class UnsupportedPlatformException(Exception):
    pass


def _show_file_darwin():
    subprocess.check_call(["open", "--", path])

def _show_file_linux():
    subprocess.check_call(["xdg-open", "--", path])

def _show_file_win32():
    subprocess.check_call(["explorer", "/select", path])

_show_file_func = {'darwin': _show_file_darwin, 
                   'linux': _show_file_linux,
                   'win32': _show_file_win32}

try:
    show_file = _show_file_func[sys.platform]
except KeyError:
    raise UnsupportedPlatformException


# then call show_file() as usual