2015-02-14 5 views
1

Я пытаюсь улучшить Bash to Python translator.перевод bash pre/post приращение/декремент на python

Bash позволяет ++ и --, в то время как Python этого не делает. Многие люди предположили, что ++x можно переписать как x += 1. Но это игнорирует требование, один в состоянии восстановить полученное значение x до или после того, как увеличение/уменьшение в рамках потенциально сложного выражения Баш, например:

x=$((++y + z--)). 

Я не могу найти способ преобразования выше к python, потому что, похоже, python не допускает побочных эффектов, таких как присвоение в выражении. Откат будет состоять в том, чтобы написать функцию pre/post, которая приняла переменную или строку в качестве входных данных и изменила внешний элемент, переданный этой функции. Но я не могу решить, как изменить функцию переменных входных параметров.

Если я знал, что элемент, на котором работает, всегда был атомным значением, я мог бы изменить его, сопоставив его имя строки со словарем, чтобы восстановить это значение и, следовательно, изменить его. Но ++ должен работать с чем-нибудь, что может наброситься на него: eg ++y[1].

Есть ли способ избежать использования таких сложных выражений bash, содержащих присвоения, и разбить их на отдельные шаги python, которые создают общий расчет, выполняемый в bash, statement by statement. Это было бы довольно уродливо.

Мне просто нужно реализовать вызов по ссылке как-то в python.

+2

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

+3

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

+0

Существует поздняя запись (с 15 по 14 октября) на https://stackoverflow.com/questions/1485841/behaviour-of-increment-and-decrement-operators-in-python, которая имеет довольно уродливый, но полезный трюк для реализации pre- и postincrement в Python, выбирая переменную из локальной таблицы символов вызывающего абонента по имени. Если вы хотите пойти туда, вам нужно, но вряд ли вы найдете довольно прямое сопоставление. – Wintermute

ответ

1

Если вам действительно нужна функциональность, было бы достаточно просто создать тип Box (MutableCell), который поддерживал бы мутирующие операторы, такие как preincrement и postincrement. Но также было бы много накладных расходов, в частности, так как вам придется перевести ((i=j)) в i = Box(j.unbox()) (или i.reset(j.unbox()) если бы вы знали i уже существовал.

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

class Box(object): 
    __slots__ = ["value"] 
    def __init__(self, value=None): 
    self.value = value 
    def unbox(self): 
    return self.value 
    def reset(self, value=None): 
    self.value = value 
    return value 
    def preincrement(self,inc=1): 
    self.value += inc 
    return self.value 
    def postincrement(self,inc=1): 
    tmp = self.value 
    self.value += inc 
    return tmp 

Тогда вы можете перевести, например, x[i++] = --z + (t += 2) * u (ЮК!) в:

x[i.postincrement()] = (Box(z.preincrement(-1) 
         + t.preincrement(2) * u.unbox()) 

O r вы можете использовать x[i.postincrement()].reset(...), если вы ранее создали x как defaultdict(Box).

Но это действительно сложно поверить, что это стоит накладных расходов.