【问题标题】:How can I write Python code to support both Windows and Linux?如何编写 Python 代码以同时支持 Windows 和 Linux?
【发布时间】:2019-11-02 11:44:43
【问题描述】:

我有一些代码需要在 Windows 和 Linux 上执行非常相似的操作。不幸的是,我需要几个特定于系统的功能(例如隐藏文件:Python cross platform hidden file)。编写代码以提高可读性和可维护性的最佳方式是什么?

当前代码使用许多if 语句在不同平台上表现不同。我考虑的另一种方法是将代码拆分为两个单独的函数,一个用于 Windows,一个用于 Linux,但这意味着在两个地方更新代码的主要部分。

请注意,代码的主要部分比这要长得多且复杂得多。

组合方法(最大的可维护性,但有很多 if 语句):

import os

def sort_out_files():
    if is_linux:
        do_linux_preparations()
    else:
        do_windows_preparations()

    # Main part of the code:
    for file in os.listdir(folder):
        if is_correct_file(file):
            if is_linux:
                do_main_actions_for_linux()
            else:
                do_main_actions_for_windows()

    if is_linux:
        do_linux_tidying_up()
    else:
        do_windows_tidying_up()

单独的方法(需要更多的维护,但需要更少的if 语句):

import os

def sort_out_files_linux():
    do_linux_preparations()

    # Main part of the code:
    for file in os.listdir(folder):
        if is_correct_file(file):
            do_main_actions_for_linux()

    do_linux_tidying_up()


def sort_out_files_windows():
    do_windows_preparations()

    # Main part of the code:
    for file in os.listdir(folder):
        if is_correct_file(file):
            do_main_actions_for_windows()

    do_windows_tidying_up()

def sort_out_files():
    if is_linux:
        sort_out_files_linux():
    else:
        sort_out_files_windows()

do_preparations()do_tidying_up() 函数涉及复制文件、提取等。

is_correct_file() 检查文件是否具有正确的名称和正确的时间戳。

do_main_actions() 涉及分析、移动和隐藏文件。

以上示例都有效,但似乎不是最符合 Python 风格或实现代码长期可维护性的最佳方法。

【问题讨论】:

标签: python linux windows


【解决方案1】:

我会将仅适用于一个操作系统的所有内容放在一个文件中,但名称相同。然后你可以在你的主文件的开头添加这样的东西:

if is_linux:
    import linux_tools as tools
else:
    import windows_tools as tools

如果这两个文件具有相同的接口(例如顶级方法),它们可以互换使用。

在您的示例中,linux_toolswindows_tools 都将包含它们各自的 sort_out_files 实现,但都命名为 sort_out_files,因此您可以将其与 tools.sort_out_files 一起使用。

请记住在这些模块中保留尽可能多的通用代码。

【讨论】:

    【解决方案2】:

    为了使您的代码更易于维护,我建议您查看adapter design pattern

    例如:您可以创建一个适配器类,而不是每次需要运行特定于操作系统的函数时都调用 if 语句。在运行时,您将使用适当的特定于操作系统的实现来创建适配器,并在需要时引用它。

    适配器设计示例:

    # Adapter interface
    class Adapter:
        def SomeAction():
            raise NotImplementedError
    
        def SomeOtherAction():
            raise NotImplementedError
    
    # Windows implementation
    class WindowsAdapter(Adapter):
        def SomeAction():
            print("Windows action!")
    
        def SomeOtherAction():
            print("Windows other action!")
    
    # Linux implementation
    class LinuxAdapter(Adapter):
        def SomeAction():
            print("Linux action!")
    
        def SomeOtherAction():
            print("Linux other action!")
    

    【讨论】:

    • 我喜欢这个,但与其他解决方案相比,它需要对现有代码进行更多更改。如果需要重建,我会认真考虑使用它。
    【解决方案3】:

    为避免代码中的重复条件,您可以在专用子模块(每个平台一个子模块)中定义所有特定于平台的函数,然后有条件地导入与您的主机匹配的函数

    主文件

    if is_linux:
        import .fs_platform_windows as fs
    else:
        import .fs_platform_linux as fs
    
    def sort_out_files():
        fs.do_preparations()
    
        # Main part of the code:
        for file in os.listdir(folder):
            if is_correct_file(file):
                fs.do_main_actions()
    
        fs.do_tidying_up()
    

    显然,您需要让两个子模块实现相同的功能(具有相同的名称)。 这是某种多态性,如果您想将所有代码放在同一个文件中,您可以使用类获得相同的结果。

    【讨论】:

      猜你喜欢
      • 2013-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-20
      • 1970-01-01
      • 2010-10-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多