2015-06-17 1 views
0

Я хотел бы вывести выражение ввода пользователя в строку.Как преобразовать выражение Python в строку

Причина в том, что входное выражение определено пользователем. Я хочу вывести результат выражения, и распечатать заявление, которое приведет к этому результату.

import sys 
import shutil 

expression1 = sys.path 
expression2 = shutil.which 

def get_expression_str(expression): 
    if callable(expression): 
     return expression.__module__ +'.'+ expression.__name__ 
    else: 
     raise TypeError('Could not convert expression to string') 

#print(get_expression_str(expression1)) 
# returns : builtins.TypeError: Could not convert expression to string 
#print(get_expression_str(expression2)) 
# returns : shutil.which 

#print(str(expression1)) 
#results in a list like ['/home/bernard/clones/it-should-work/unit_test', ... ,'/usr/lib/python3/dist-packages'] 

#print(repr(expression1)) 
#results in a list like ['/home/bernard/clones/it-should-work/unit_test', ... ,'/usr/lib/python3/dist-packages'] 

Я посмотрел в Python инспектировать модуля, но даже

inspect.iscode(sys.path) 

возвращает Ложные

Для тех, кто задается вопросом, почему это реверс строки разобраны на выражение с использованием functools.partial см parse statement string

Фон.

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

Таким образом, пользователь или разработчик программы задает свои требования вместе с утверждениями о том, как получить эту информацию: выражения. Который может быть выполнен с использованием eval. Мог. Как упоминалось в StackOverflow eval, это зло. Использование eval трудно сделать безопасным с помощью черного списка, см.: http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html Использование нескольких советов SO Я использую namedtuple со строкой для сравнения с пользовательской строкой ввода и функцией.

Белый список лучше, чем черный список. Только если строка синтаксического анализа соответствует «bare_expression», тогда возвращается выражение. Этот белый список содержит дополнительную информацию, как обрабатывать f.e. «unit_of_measurement». Это объясняет, почему и почему, но это необходимо. Список namedtuples гораздо больше, чем просто белого списка и определяется:

Expr_UOfM = collections.namedtuple('Expr_UOfM', ['bare_expression', 'keylist', 'function', 'unit_of_measurement', 'attrlist']) 

namedtuple, которые соответствуют (очень ограниченный) список:

Exp_list = [Expr_UOfM('sys.path', '' , sys.path, un.STR, []), 
      Expr_UOfM('shutil.which', '', shutil.which, None, [])] 

Этот список может быть очень длинным и контент имеет решающее значение для дальнейшей правильной обработки. Обратите внимание, что первое и третье поля очень похожи. Должна быть единая точка отсчета, но для меня это в этот момент невозможно. Обратите внимание на строку: 'sys.path' равно (часть) ввода пользователя, а выражение: sys.path является частью списка namedtuple. Хорошее разделение, ограничивающее возможное злоупотребление. Если строка и выражение не на 100% идентичны, может возникнуть странное поведение, которое очень сложно отлаживать. Поэтому он хочет, чтобы функция get_expression_str проверяла идентичность первого и третьего полей. Просто для полной надежности программы .

Я использую Python 3.4

+0

try 'str (выражение)' – SomethingSomething

+0

Я сделал это, посмотрю линию 4e снизу, но безуспешно. – Bernard

+0

Итак, где вход пользователя? Вы не начинаете * со строкой (например, 'sys.path'')? – jonrsharpe

ответ

0

Почему бы не использовать eval?

>>> exp1 = "sys.path" 
>>> exp2 = "[x*x for x in [1,2,3]]" 
>>> eval(exp1) 
['', 'C:\\Python27\\lib\\site-packages\\setuptools-0.6c11-py2.7.egg', 'C:\\Pytho 
n27\\lib\\site-packages\\pip-1.1-py2.7.egg', 'C:\\Python27\\lib\\site-packages\\ 
django_celery-3.1.1-py2.7.egg', 'C:\\Python27\\lib\\site-packages\\south-0.8.4-p 
y2.7.egg', 'C:\\Windows\\system32\\python27.zip', 'C:\\Python27\\DLLs', 'C:\\Pyt 
hon27\\lib', 'C:\\Python27\\lib\\plat-win', 'C:\\Python27\\lib\\lib-tk', 'C:\\Py 
thon27', 'C:\\Python27\\lib\\site-packages', 'C:\\Python27\\lib\\site-packages\\ 
PIL'] 
>>> eval(exp2) 
[1, 4, 9] 
+0

Мое значение - обратная сторона eval. Вход eval - это строка, а выход - выражение. Я хочу ввести выражение и вывести строку. Итак, в вашем примере [1, 4, 9] возвращает exp2, что кажется мне невозможным. Кстати, eval очень опасен для использования, поэтому я использую functools.partial – Bernard

+0

Это кажется невозможным. Я не знаю, что такое сценарий использования. Если вы разбираете код python, подумайте об использовании ast. – NeoWang

+0

Я смотрел на аш, но не смог найти решение. Не могли бы вы создать некоторый код для sys.path, используя модуль ast? – Bernard

Смежные вопросы