Форум сайта python.su
Коллеги, у меня возникла следующая проблема. Пишу на питоне интерпретатор некоторого языка. Выполняю разбор выражения, например, такого вида: F(x,y)=25 - x^2 - y^2. Затем мне нужно МНОГО раз вычислять F(x,y) при различных значениях аргументов. На С++ я это делал достаточно просто. Сохранял указатели на x и y в дереве разбора, затем, меняя по соответствующим адресам значения x и y, вычислял значение F для нужных мне аргументов. Как это сделать на питоне? Короче говоря, как в питоне работать с указателями?
Офлайн
В питоне вы почти всегда работаете с указателями. Объект любого пользовательского класса ВСЕГДА присваивается и передается по ссылке. У вас может возникнуть вопрос как присвоить объект по значению - это и правда нельзя сделать тривиально, а вот с присвоением значения по ссылке вопросов нет, потому что это поведение по умолчанию. Посему вас вопрос решается просто - он просто не стоит как таковой.
Офлайн
Смотрите. Я реализовал класс Tree который имеет несколько конструкторов (с одним параметром для обработки чисел, двумя – для обработки унарных операций и тремя - бинарных). Он используется для разбора выражений. Например, выражений «x + y» с помощью данного класса может быть описано так (приблизительно):
…
exp = Tree(Tree(x),’+’, Tree(y))
…
Как мне потом поменять значения x и y, которые сохранились в объектах класса Tree?
Офлайн
SeregaGomenВ питоне нет перегрузки методов.
Я реализовал класс Tree который имеет несколько конструкторов
SeregaGomenВ чем проблема? Берете и меняете: obj.x = x
Как мне потом поменять значения x и y
Офлайн
“В чем проблема? Берете и меняете: obj.x = x”
Как мне в переменной exp (exp = Tree(Tree(x),’+’, Tree(y))) поменять что-то? Это же по сути набор вызовов большого количества конструкторов класса Tree.
Например, у меня есть выражение “x^2+sin(x)+3”. Дерево его разбора будет иметь приблизительно такой вид: exp = Tree(Tree(Tree(Tree(x),'^',Tree(2)),'+',Tree(x,'sin')),'+',Tree(3)).
Как в переменной exp, которая вернулась как результат вызова некоторой функции (точнее большого их числа) что-то менять?
Офлайн
SeregaGomenКакая разница, откуда взялась переменная? Если на момент совершаемых вами операций она существует, то вы можете изменить её атрибуты.
Как в переменной exp, которая вернулась как результат вызова некоторой функции (точнее большого их числа) что-то менять?
SeregaGomen
”. Дерево его разбора будет иметь приблизительно такой вид: exp = Tree(Tree(Tree(Tree(x),'^',Tree(2)),'+',Tree(x,'sin')),'+',Tree(3)).
Офлайн
Я это понимаю. Проблема в том, что на момент разбора выражения “x+y” я не знаю значений x и y.
Класс Tree (частично) выглядит так:
# Абстрактный базовый класс значения выражения
class TNode:
@abstractmethod
def value(self):
raise NotImplementedError('Method TNode.value is pure virtual')
# Класс, реализующий дерево разбора арифметических выражений
class TTree:
def __init__(self, *args):
if len(args) == 0:
self.node = TRealNode(0)
elif len(args) == 1:
self.node = TRealNode(args)
elif len(args) == 2:
self.node = TUnaryNode(args, args)
elif len(args) == 3:
self.node = TBinaryNode(args, args, args)
def value(self):
return self.node.value()
# Вещественная переменная
class TRealNode(TNode):
def __init__(self, val):
self.__val__ = val
def value(self):
return self.__val__
Так вот, когда обрабатывается выражение “x+y”, то строится переменная вида: exp = Tree(Tree(x),'+',Tree(y)), где первоначально x и y имеют, например, нулевые значения. Для их обработки будут построены экземпляры класса TRealNode, Как мне поменять в них значения ума не приложу В С++ я бы сделал еще один конструктор, принимающий указатель на число. А как тут быть?
Офлайн
SeregaGomenСделай x и y объектами с методами set() и get().
На С++ я это делал достаточно просто. Сохранял указатели на x и y в дереве разбора, затем, меняя по соответствующим адресам значения x и y, вычислял значение F для нужных мне аргументов. Как это сделать на питоне? Короче говоря, как в питоне работать с указателями?
SeregaGomenСмотри на указатель в C++ как на число с множеством операций над ним - как на объект с методами. Нет такого понятия “указатель”, это просто такой придуманный объект с операциями, встроенный в язык. Придумали его раньше C++, но по сути это просто алгебраическая структура, состоящая из множества (носителя) и нескольких операций над элементами этого множества (операций).
В С++ я бы сделал еще один конструктор, принимающий указатель на число.
Отредактировано py.user.next (Июнь 24, 2017 21:36:55)
Офлайн
Ок, спасибо!
Попробую…
Офлайн
> Выполняю разбор выражения, например, такого вида: F(x,y)=25 - x^2 - y^2. Затем мне нужно МНОГО раз вычислять F(x,y) при различных значениях аргументов. На С++ я это делал достаточно просто. Сохранял указатели на x и y в дереве разбора, затем, меняя по соответствующим адресам значения x и y, вычислял значение F для нужных мне аргументов.
Если переопределить метод __call__ то можно получить функтор который можно вызывать как функцию. Если сделать дерево разбора функтором, то проблема будет решена:
exp = Tree(Tree(x),'+',Tree(y)) print [ exp(x,y) for x,y in zip(xrange(10), xrange(10)) ]
Отредактировано Rodegast (Июнь 24, 2017 22:32:15)
Офлайн