Подтвердить что ты не робот

Использование "из __future__ import division" в моей программе, но оно не загружено моей программой

Я написал следующую программу на Python 2, чтобы выполнить вычисления метода Ньютона для моего набора математических задач, и, хотя он работает отлично, по причинам, которые мне неизвестны, когда я первоначально загружал его в ipython с помощью %run -i NewtonsMethodMultivariate.py, разделение Python 3 не импортируется. Я знаю это, потому что после загрузки моей программы Python ввод x**(3/4) дает "1". После ручного импорта нового деления x**(3/4) остается x**(3/4), как и ожидалось. Почему это?

# coding: utf-8
from __future__ import division
from sympy import symbols, Matrix, zeros

x, y = symbols('x y')
X = Matrix([[x],[y]])
tol = 1e-3

def roots(h,a):
  def F(s):
    return h.subs({x: s[0,0], y: s[1,0]})
  def D(s):
    return h.jacobian(X).subs({x: s[0,0], y: s[1,0]})
  if F(a) == zeros((2,1)):
    return a
  else:
    while (F(a)).norm() > tol:
      a = a - ((D(a))**(-1))*F(a)
      print a.evalf(10)

Я бы использовал Python 3, чтобы избежать этой проблемы, но мой дистрибутив Linux отправляет Sympy для Python 2. Благодаря помощи, которую может предоставить любой пользователь.

Кроме того, в случае, если кто-то задавался вопросом, я еще не обобщил этот script для nxn якобианцев, и мне приходилось иметь дело только с 2x2 в моем наборе проблем. Кроме того, я нарезаю нулевую матрицу 2x2 вместо использования команды zeros(2,1), потому что Sympy 0.7.1, установленный на моей машине, жалуется, что "zeros() принимает ровно один аргумент", хотя wiki предлагает другое. Возможно, эта команда предназначена только для версии git. (Спасибо eryksun за исправление моих обозначений, что устранило проблему с помощью функции нулей.)

4b9b3361

Ответ 1

Обе команды ipython -i и run -i в ipython интерпретаторе игнорируют from __future__ import division в print05.py script.

$ cat print05.py 
from __future__ import division
print(1/2)

В консоли ipython:

In [1]: print 1/2
0
In [2]: run -i print05.py
0.5
In [3]: division
Out[3]: _Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)
In [4]: print 1/2
0
In [5]: from __future__ import division
In [6]: print 1/2
0.5

execfile и import дают тот же результат:

>>> print 1/2
0
>>> execfile('print05.py')
0.5
>>> print 1/2
0
>>> from __future__ import division
>>> print 1/2
0.5

from __future__ import division не должен влиять на исходный код из разных модулей, иначе он сломает код в других модулях, которые не ожидают его присутствия.

Здесь from __future__ import division имеет эффект:

$ python -i print05.py
0.5
>>> print 1/2
0.5
>>> division
_Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)

В этом случае имя модуля __main__ внутри print05.py и в подсказке.

Здесь первый print 1/2 выполняется в модуле print05, второй в модуле __main__, поэтому он также работает так, как ожидалось:

$ python -im print05
0.5
>>> print 1/2
0

И вот что-то не так:

$ ipython -i print05.py
0.5
In [1]: division
Out[1]: _Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)
In [2]: print 1/2
0

Документы для __future__ говорят:

Если интерпретатор запущен с опцией -i, передается scriptимя для выполнения, а script включает будущий оператор, он будет действовать в интерактивном сеансе, запущенном после того, как scriptвыполняется.

Так что это может быть ошибка в ipython, если его параметр -i пытается эмулировать ту же опцию python.

Ответ 2

SymPy также предоставляет script - isympy - это оболочка для IPython, которая выполняет некоторые общие команды, включая импорт деления из будущего. Это очень удобно, и в новых версиях IPython (0.11+) он также позволяет создавать автоматические конструкции символов (что приятно, поскольку я всегда забываю); запустите его с параметром -a.

Что касается Python 3, в версии разработки есть поддержка, и следующая версия будет иметь его; когда дистрибутивы собираются упаковать его, я не знаю.