2008-12-09 4 views
1

Я хотел бы создать простой формат файла/DSL, который позволит моим пользователям вводить данные. Моя система находится в python, и использование парсера python является привлекательным. Синтаксис, подобный этому для определения элемента данных, кажется довольно удобным.Аргументы метода Python с пробелами

Allocation(Param1 = Val1, Param2 = Val2) 

Однако он не поддерживает имена параметров с пробелами.

Allocation(Param 1 = Val1, Param 2 = Val2) 

Совместимые версии парсинга Python могут выглядеть следующим образом, но не очень удобны для пользователя.

Allocation(("Param 1",Val1), ("Param 2",Val1)) 
Allocation(**{"Param 1":Val1, "Param 2":Val1}) 

Есть ли способ сделать это более читаемым в python?

ответ

1

Вот мои предпочтения.

AllocationSet(
    Alloc(name="some name", value=1.23), 
    Alloc(name="another name", value=2.34), 
    Alloc(name="yet another name", value=4.56), 
) 

Это относительно легкие декларации классов для создания. Полученная структура приятно обрабатывать.

0

Вы можете сделать это:

def Allocation(**kwargs): 
    print kwargs 

myargs = {"Param 1":Val1, "Param 2":Val1} 
Allocation(**myargs) 

Edit: Ваша правка теперь включает в себя мой ответ, нет, нет более простой способ, чтобы иметь пробелы в именованных аргументов.

1

Если меня не спутать вашу основную предпосылку здесь, нет ничего, чтобы остановить вас от написания класса, который разбирает свой собственный синтаксис, а затем, используя этот пользовательский синтаксис как одного аргумента строки:

Allocation("Param 1=Check Up; Param 2=Mean Value Theorem;") 

В в этом примере точки с запятой действуют как разделители имен и значений, а equals представляет разделитель имени-значения. Более того, вы можете легко настроить ваш синтаксический анализатор для принятия пользовательских разделителей как части конструктора объектов.

Если это кажется слишком сложным, чтобы написать парсер, считает, что (для синтаксиса, таких как это) вы можете получить свои значения, просто разделив строку на

/\s*;\s*/ 

, а затем на

/\s*=\s*/ 

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

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

3

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

Allocation(Param1 = Val1, Param2 = Val2) 

К этому:

Allocation(Param 1 = Val1, Param 2 = Val2) 

, чтобы сделать эту большую разницу? Я уверен, что есть способ сделать то, что вы хотите сделать, но моя первая проблема заключается в том, что усилия будут стоить результата.

Моя цель - предоставить DSL, который может использоваться для ввода данных в систему. В приведенном выше сценарии параметрами будут имена людей, а значения будут процентами.

У меня есть лучшее понимание того, что вы хотите сделать сейчас, но я все же думаю, что вам, возможно, придется пожертвовать некоторой удобочитаемостью, чтобы получить то, что вы хотите. Лично я бы с чем-то вроде:

Allocation(
    { 'name1' : value1, 
     'name1' : value2, } 
) 

Если это не то, что вы можете пойти с, то вы, возможно, захотите пересмотреть, хотите ли вы использовать Python для вашего DSL или идти с чем-то доморощенный. Разрешение пробелов допускает слишком много двусмысленностей для большинства языков программирования.

Если вы все еще хотите преуспеть в использовании с помощью python, вы можете рассмотреть возможность публикации в C-API SIG (SIGS) или, возможно, python-dev list (в крайнем случае). Единственный способ, с помощью которого я мог бы это сделать, - включить интерпретатор python в программу C/C++ и сделать с ним какой-то хакинг (что может быть сложно!).

+0

+1: имена параметров с пробелами не стоят агонии и на самом деле не помогают. Используйте _ вместо пробелов. – 2008-12-09 12:43:25