为平台定义具有变体的函数的最正确方法
Most correct way to define a function with variations for platforms
今天我运行跨越了this answer,它定义了一个函数after确定系统平台
我一直假设(或者更确切地说,从未真正考虑过)确定跨平台函数正确行为的条件应该放在定义中。
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])
我不知道以上任何一个片段是否有效,但这无论如何都不是问题的一部分。
第一个版本在每次调用show_file
时都会进行平台检查;第二个没有。不过,它可能不会让它变慢到足够重要。
将 show_file()
函数定义放在条件语句中的一个结果是,尝试在不受支持的平台上使用此函数将引发 NameError
。将条件语句放在 show_file
函数中将导致它无声地失败,除非您还在最后的 else
块中包含 raise
。
由你决定哪个更好。就个人而言,我更喜欢在不受支持的平台上出现明显的错误,但我认为为了清楚起见,这可能最好作为最终 else
条件处理,因此异常的原因非常清楚。
两种情况之间的效率可以忽略不计。我会更关心代码的可读性和异常处理。
"best way" 可能取决于您的优先级。
解决此类问题的一种方法可能是优先考虑可读性,并准备代码以提取抽象。它可能沿着这些路线,如果由于不支持平台而无法进行正确的功能分配,则抛出异常。
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
今天我运行跨越了this answer,它定义了一个函数after确定系统平台
我一直假设(或者更确切地说,从未真正考虑过)确定跨平台函数正确行为的条件应该放在定义中。
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])
我不知道以上任何一个片段是否有效,但这无论如何都不是问题的一部分。
第一个版本在每次调用show_file
时都会进行平台检查;第二个没有。不过,它可能不会让它变慢到足够重要。
将 show_file()
函数定义放在条件语句中的一个结果是,尝试在不受支持的平台上使用此函数将引发 NameError
。将条件语句放在 show_file
函数中将导致它无声地失败,除非您还在最后的 else
块中包含 raise
。
由你决定哪个更好。就个人而言,我更喜欢在不受支持的平台上出现明显的错误,但我认为为了清楚起见,这可能最好作为最终 else
条件处理,因此异常的原因非常清楚。
两种情况之间的效率可以忽略不计。我会更关心代码的可读性和异常处理。
"best way" 可能取决于您的优先级。
解决此类问题的一种方法可能是优先考虑可读性,并准备代码以提取抽象。它可能沿着这些路线,如果由于不支持平台而无法进行正确的功能分配,则抛出异常。
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