#python
#python
Вопрос:
Я управляю довольно большим пакетом квантовой химии на основе Python, PyQuante. В настоящее время я пытаюсь установить различные значения по умолчанию, чтобы пользователи могли выбирать между различными параметрами во время выполнения.
Например, у меня есть три разных метода для вычисления интегралов отталкивания электронов. Давайте назовем их a, b, c. Раньше я просто выбирал тот, который мне больше нравился (скажем, c), и жестко подключал его к модулю, который вычисляет эти интегралы.
Теперь я изменил это, чтобы использовать модуль, Defaults.py, который содержит все такие жесткие провода. Но это устанавливается во время компиляции / установки. Теперь я хотел бы, чтобы пользователи могли переопределять эти параметры во время выполнения, скажем, используя .pyquanterc.py файл.
В моих встроенных подпрограммах в настоящее время у меня есть что-то вроде
from Defaults import integral_method
Я знаю о словарях и методе .update(). Но я не знаю, как бы я использовал это в реальной жизни. Мой модуль по умолчанию выглядит следующим образом
integral_method = c
должен ли я изменить конец Defaults.py чтобы найти .pythonrc.py файл и переопределить эти значения? Например.
if os.path.exists('$HOME/.pythonrc.py'): do_something
Если да, то как должно выглядеть do_something?
Комментарии:
1. «Но это устанавливается во время компиляции / установки»? Не совсем. Модуль выполняется вместе со всем остальным. «Компиляция» мало что значит в Python. Если модуль находится в каталоге пользователя вместо каталога установки, то пользователь может изменить его, верно?
2. Смысл, в котором я имел в виду, что это было установлено при установке, заключается в том, что я представляю вариант использования, когда сопровождающий устанавливает программное обеспечение, что означает, что все Defaults.py определения устанавливаются в локальный каталог пакетов сайта. Я хочу, чтобы люди могли легко изменять эти настройки.
3. «означает, что все Defaults.py определения устанавливаются в пакеты локального сайта»? Почему? Если вам нужна гибкость, зачем устанавливать конфигурацию?
Ответ №1:
С вашей текущей настройкой пользователь может довольно легко изменять функции по умолчанию в своих скриптах:
import Defaults
Defaults.integral_method = somefunc
Если пользователь добавит это в свой скрипт, все ваши модули, использующие integral_method
from Defaults
, будут использовать somefunc
для вычисления интегралов.
Комментарии:
1. Динь-динь-динь! Это должно было быть очевидно для меня, но не было. Кажется, это самый простой способ сделать это, поскольку мне на самом деле ничего не нужно делать. Хотя я нахожу приведенное ниже решение factory class также довольно приятным. Большое спасибо!
Ответ №2:
Я мог бы сделать это с помощью заводского класса.
class IntegralSolver:
"""
Factory class containing methods for solving integrals.
>>> solver = IntegralSolver("method1")
>>> solver(x)
# solution via method1
Can also be used directly:
>>> IntegralSolver.method2(x)
# solution via method2
"""
def __init__(self, method):
self.__call__ = getattr(self, method)
@staticmethod
def method1(x):
return method1_solution
@staticmethod
def method2(x):
return method2_solution
Комментарии:
1. Я тоже думал в этом направлении. Как вы думаете, помогло бы наличие набора функций, определенных с помощью лямбд, чтобы их можно было вызывать во время выполнения?
2. Очень элегантно. Обычно я избегаю подобных методов, но ваш код настолько чистый, что я не могу представить, почему я не делаю это постоянно. Большое спасибо!
Ответ №3:
Это действительно зависит от того, как ваш пользователь запускает набор инструментов. Если они каждый раз меняют код Python, достаточно просто установить блок в верхней части с надписью OPTIONS. Если они запускают его из командной строки, используйте библиотеку argparse, чтобы позволить им переключать параметры в командной строке. Возможно, попросите его прочитать параметры из файла с помощью ConfigParser, чтобы прочитать файл по умолчанию с вашими параметрами, и, если пользователь установит его, дополнительный файл со своими параметрами.
Комментарии:
1. Итак, вы предлагаете, чтобы я вручную переопределил значения в Defaults.py модуль (в соответствии с тем, что sth предложил выше) с использованием argparse (или getopt для меня, я старой школы)? Это могло бы быть отличным дополнением к методу, к которому я уже склонялся. Спасибо!
2. Я обнаружил, что две вышеперечисленные библиотеки позволяют очень легко преобразовать скрипт на Python в полноценную программу командной строки. Таким образом, вам не нужно думать о маркировании входной строки и ее синтаксическом анализе, что сложно, вы просто определяете свои флаги и их значения по умолчанию.