Вопрос

Я думал об этом слишком долго и не получил никакой идеи, может быть, некоторые из вас могут помочь.

У меня есть папка сценариев Python, все из которых имеют одинаковое окружающее тело (буквально, я создал его из скрипта оболочки), но иметь один кусок, который отличается от всех них. Другими словами:

Top piece of code (always the same)
Middle piece of code (changes from file to file)
Bottom piece of code (always the same)

И я понял сегодня, что это плохое представление, например, если я хочу изменить что-то из верхних или нижних сечений, мне нужно написать сценарий оболочки, чтобы сделать это. (Не то, что это сложно, просто похоже, что это очень плохой код).

Так что я хочу сделать, есть один внешний скрипт Python, который похож на это:

Top piece of code
Dynamic function that calls the middle piece of code (based on a parameter)
Bottom piece of code

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

Поэтому я придумал еще два решения:

  1. Я мог бы записать кучу заявлений, чтобы запустить каждый сценарий на основе определенного параметра. Я отклонил это, так как даже хуже, чем предыдущий дизайн.
  2. Я мог бы использовать:

    os.command (sys.argv [0] scriptname.py)

    Что будет запускать скрипт, но призывая питона называть Python, не кажется мне очень элегантным для меня.

Так у кого-нибудь есть какие-то другие идеи? Спасибо.

Это было полезно?

Решение

Если вы знаете имя функции как строку и имя модуля как строку, то вы можете сделать

mod = __import__(module_name)
fn = getattr(mod, fn_name)
fn()

Другие советы

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

from topAndBottom import top, bottom
top()
# do middle stuff
bottom()

В дополнение к нескольким ответам уже опубликовано, рассмотрите Метод шаблона Шаблон дизайна: сделать абстрактный класс, такой как

class Base(object):
    def top(self): ...
    def bottom(self): ...
    def middle(self): raise NotImplementedError
    def doit(self):
        self.top()
        self.middle()
        self.bottom()

Каждый модуль подключаемых, затем делает класс, который наследует из этого Base и должен переопределить middle с соответствующим кодом.

Возможно, не гарантировано для этого простого случая (вам все еще нужно импортировать правильный модуль, чтобы создать свой класс и вызов doit На нем), но все еще стоит иметь в виду (вместе со своими многочисленными вариациями Pythonic, которые я наглядно объяснил во многих технологических переговорах, теперь доступных на YouTube) для случаев, когда число или сложность «плюшек штук» продолжает расти - метод шаблона (Несмотря на свое ужасное имя ;-) - это сплошной, хорошо доказанный и высокомасштабный шаблон [[иногда слишком жесткий, но это именно то, что я обращаюсь в тех много технических переговоров - и эта проблема не применяется к этому конкретному Используйте Case]].

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

Это будет работать просто хорошо - использовать __import__ встроенный или, если у вас очень сложный макет, укреплять Модуль для импорта вашего сценария. И тогда вы можете получить функцию module.__dict__[funcname] Например.

Импорт модуля (как объяснено в других ответах), безусловно, является более чистым способом для этого, но если по какой-то причине это не работает, пока вы не делаете ничего странного, вы можете использовать exec. Отказ Он в основном запускает содержимое другого файла, как если бы он был включен в текущий файл в точке, где exec называется. Это самое близкое, что Python имеет к source Заявление о виду включено во многие снаряды. Как минимум, что-то вроде этого должно работать:

exec(open(filename).read(None))

Как насчет этого?

function do_thing_one():
   pass

function do_thing_two():
   pass

dispatch = { "one" : do_thing_one,
             "two" : do_thing_two,
           }

# do something to get your string from the command line (optparse, argv, whatever)
# and put it in variable "mystring"

# do top thing
f = dispatch[mystring]
f()
# do bottom thing
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top