Как я могу написать код Python для поддержки как Windows, так и Linux? - PullRequest
0 голосов
/ 02 ноября 2019

У меня есть код, который должен делать очень похожие вещи как в Windows, так и в Linux. К сожалению, мне требуется несколько системных функций (например, скрытые файлы: Python кросс-платформенный скрытый файл ). Каков наилучший способ написания кода для удобочитаемости и удобства обслуживания?

В настоящее время в коде используется множество операторов 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() включает анализ, перемещение и сокрытие файлов.

Оба приведенных выше примера работают, но не выглядят как самый Pythonic или лучший подход к долговременному сопровождению кода.

Ответы [ 3 ]

4 голосов
/ 02 ноября 2019

Я бы поместил все, что работает только для одной ОС в один файл, но с одинаковым именем. Затем вы можете добавить что-то вроде этого в начале вашего основного файла:

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

, если оба этих файла имеют одинаковый интерфейс (например, Методы верхнего уровня), они могут использоваться взаимозаменяемо.

В вашем примере linux_tools и windows_tools будут содержать свои соответствующие реализации sort_out_files, но оба будут иметь имя sort_out_files, поэтому вы можете использовать его с tools.sort_out_files.

Не забудьте сохранитькак можно больше общего кода из этих модулей.

1 голос
/ 02 ноября 2019

Чтобы избежать повторяющихся условий во всем вашем коде, вы можете определить все свои специфичные для платформы функции в выделенных подмодулях (один подмодуль на платформу), а затем условно импортировать ту, которая соответствует вашему хосту

Основной файл

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()

Очевидно, вам нужно, чтобы оба подмодуля реализовывали одинаковые функции (с одинаковыми именами). Это своего рода полиморфизм, вы можете получить тот же результат с классами, если вы хотите, чтобы весь ваш код был в одном файле.

1 голос
/ 02 ноября 2019

Чтобы сделать ваш код более понятным, я бы порекомендовал посмотреть шаблон проектирования адаптера .

Например: вместо вызова оператора 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!")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...