Python-future: Konversi pembagian yang salah ke old_div

Dibuat pada 30 Jan 2019  ·  12Komentar  ·  Sumber: PythonCharmers/python-future

Contoh kode

Kode berikut berisi pembagian gaya lama.

(x / 2 * 3.0)

Hasil yang diharapkan

Hasil menjalankan kode di atas dengan nilai arbitrer yang ditetapkan ke x harus sebagai berikut, di mana tanda kurung secara eksplisit menunjukkan urutan operasi (x / 2) * 3.0 . Atau ditulis dalam urutan lain, hasilnya harus dievaluasi sebagai x * (3.0 / 2) .

Masalah

Setelah kita menjalankan futurize pada kode di atas, old_div akan disisipkan oleh fixture fix_division_safe . Namun seperti yang dapat dilihat di diff di bawah ini, fungsi dipanggil dengan urutan argumen yang salah.

$ futurize --stage2 src/example.py
RefactoringTool: Refactored src/example.py
--- src/example.py      (original)
+++ src/example.py      (refactored)
@@ -1 +1,3 @@
-(x / 2 * 3.0)
+from __future__ import division
+from past.utils import old_div
+(old_div(x, 2 * 3.0))
RefactoringTool: Files that need to be modified:
RefactoringTool: src/example.py

Konversi yang diharapkan

Seperti yang telah dinyatakan di bagian 'hasil yang diharapkan', konversi yang benar seharusnya: (old_div(x, 2) * 3.0)

0.18 bug

Komentar yang paling membantu

Saya juga memiliki masalah ini, menjalankan futurize 0.17.1 di Python 2.7.16. Contoh ini menggambarkan masalah:

$ echo 'x = 100/10 * 10' | futurize --stage2 -

RefactoringTool: Refactored <stdin>
--- <stdin> (original)
+++ <stdin> (refactored)
@@ -1 +1,3 @@
-x = 100/10 * 10
+from __future__ import division
+from past.utils import old_div
+x = old_div(100,10 * 10)
RefactoringTool: Files that need to be modified:
RefactoringTool: <stdin>

Perhatikan bahwa 100/10 * 10 (==100) dikonversi menjadi old_div(100,10 * 10) (==1). Ini sepertinya bug utama bagi saya.

Semua 12 komentar

Atau ditulis dalam urutan lain, hasilnya harus dievaluasi sebagai x * (3.0 / 2) .

Meskipun secara matematis setara, ini tidak sama dengan Python 2. Jika x adalah int , maka x / 2 akan terpotong terlebih dahulu dalam beberapa kasus, sedangkan (3.0 / 2) akan selalu menjadi 1,5 dan tidak pernah terpotong.

Meskipun tentu saja, itu tidak mengubah bug.

Saya juga berpikir begitu, itulah sebabnya saya menggunakan Python 2.7.15 serta Python 3.7.1 untuk menjalankan contoh dan memvalidasi bahwa mereka menunjukkan perilaku yang sama. Senang mendengar bahwa niat pertama saya tidak sepenuhnya salah.

Mungkin itu juga terhubung ke OS? Saya menjalankan contoh di Windows 7 x64.

Bisakah Anda memberikan contoh dalam kasus mana Python 2 akan mengevaluasi ekspresi dengan cara lain?

>>> y = range(10)

>>> [x / 2 * 3.0 for x in y]
[0.0, 0.0, 3.0, 3.0, 6.0, 6.0, 9.0, 9.0, 12.0, 12.0]

>>> [x * (3.0 / 2) for x in y]
[0.0, 1.5, 3.0, 4.5, 6.0, 7.5, 9.0, 10.5, 12.0, 13.5]

(Konversi yang Anda harapkan tentu saja merupakan hasil yang benar.)

Benar-benar apa yang saya harapkan. Namun saya secara eksplisit menguji menggunakan 1 untuk x dan mendapatkan 1,5 sebagai hasilnya.

Saya juga lupa menyebutkan, bahwa ada keluaran kode yang berbeda jika Anda tidak menggunakan tanda kurung. Dalam hal ini futurize akan menghasilkan konversi yang benar.

1 / 2 * 3.0 - - > old_div(1, 2) * 3.0

Saya menemukan bug yang sama dan sedang memperbaikinya di cabang saya .
Sepertinya perubahan saya memperbaiki masalah ini sebagai berikut:

$ cat sample.py          
x =  10
(x / 2 * 3.0)

keluaran asli

$ futurize sample.py 
RefactoringTool: Skipping optional fixer: idioms
RefactoringTool: Skipping optional fixer: ws_comma
RefactoringTool: Refactored sample.py
--- sample.py   (original)
+++ sample.py   (refactored)
@@ -1,2 +1,4 @@
+from __future__ import division
+from past.utils import old_div
 x =  10
-(x / 2 * 3.0)
+(old_div(x, 2 * 3.0))
RefactoringTool: Files that need to be modified:
RefactoringTool: sample.py

keluaran baru

$ futurize sample.py
RefactoringTool: Skipping optional fixer: idioms
RefactoringTool: Skipping optional fixer: ws_comma
RefactoringTool: Refactored sample.py
--- sample.py   (original)
+++ sample.py   (refactored)
@@ -1,2 +1,4 @@
+from __future__ import division
+from past.utils import old_div
 x =  10
-(x / 2 * 3.0)
+(old_div(x, 2) * 3.0)
RefactoringTool: Files that need to be modified:
RefactoringTool: sample.py

Saya akan membuat permintaan tarik ketika saya melihat waktu..

Berikut adalah lebih banyak contoh.

Saya juga lupa menyebutkan, bahwa ada keluaran kode yang berbeda jika Anda tidak menggunakan tanda kurung. Dalam hal ini futurize akan menghasilkan konversi yang benar.

1 / 2 * 3.0 - - > old_div(1, 2) * 3.0

Bertentangan dengan apa yang Anda katakan, saya melihat 1 / 2 * 3.0 dikonversi menjadi old_div(1, 2 * 3.0) salah menggunakan kode saat ini di master..

$ cat sample2.py
1 / 2 * 3.0
x =  10
x / 2
x / 2.0
x / 2 * 3
x / (2 * 3)
x * 2 / 3

keluaran asli

$ futurize sample2.py
RefactoringTool: Skipping optional fixer: idioms
RefactoringTool: Skipping optional fixer: ws_comma
RefactoringTool: Refactored sample2.py
--- sample2.py  (original)
+++ sample2.py  (refactored)
@@ -1,7 +1,9 @@
-1 / 2 * 3.0
+from __future__ import division
+from past.utils import old_div
+old_div(1, 2 * 3.0)
 x =  10
-x / 2
+old_div(x, 2)
 x / 2.0
-x / 2 * 3
-x / (2 * 3)
-x * 2 / 3
+old_div(x, 2 * 3)
+old_div(x, (2 * 3))
+old_div(x * 2, 3)
RefactoringTool: Files that need to be modified:
RefactoringTool: sample2.py

keluaran baru

$ futurize sample2.py
RefactoringTool: Skipping optional fixer: idioms
RefactoringTool: Skipping optional fixer: ws_comma
RefactoringTool: Refactored sample2.py
--- sample2.py  (original)
+++ sample2.py  (refactored)
@@ -1,7 +1,9 @@
-1 / 2 * 3.0
+from __future__ import division
+from past.utils import old_div
+old_div(1, 2) * 3.0
 x =  10
-x / 2
+old_div(x, 2)
 x / 2.0
-x / 2 * 3
-x / (2 * 3)
-x * 2 / 3
+old_div(x, 2) * 3
+old_div(x, (2 * 3))
+old_div(x * 2, 3)
RefactoringTool: Files that need to be modified:
RefactoringTool: sample2.py

PR dibuat (https://github.com/PythonCharmers/python-future/pull/441)

Saya juga mengamati bahwa old_div disisipkan bahkan ketika operan kiri dan kanan adalah float, mis.

1.0/1024.0

menjadi

old_div(1.0,1024.0)

Saya pikir konversi ini tidak perlu karena pembagian di mana kedua operan adalah float menghasilkan hasil yang sama, baik di Python 2 dan Python 3.

@mattgathu Versi futurize dan Python mana yang Anda gunakan? Dengan Python 3.7.2 dan futurize 0.17.1 (yang terbaru di PyPI), 1.0/1024.0 tetap utuh saat futurize d.

$ python --version
Python 3.7.2
$ futurize --version
0.17.1

$ cat test.py
1.0 / 1024.0
1   / 1024.0
1.0 / 1024

$ futurize test.py
RefactoringTool: Skipping optional fixer: idioms
RefactoringTool: Skipping optional fixer: ws_comma
RefactoringTool: No files need to be modified.

Berikut adalah versi saya:

$ python -V
Python 2.7.16
$ futurize --version
0.16.0

Saya telah memutakhirkan ke

Memang tampaknya v0.17.0 menyertakan peningkatan untuk melewati konversi yang tidak perlu.

https://github.com/PythonCharmers/python-future/releases/tag/v0.17.0

Perbaiki fix_division_safe untuk mendukung konversi ekspresi kompleks yang lebih baik, dan lewati pembagian float yang jelas.

Saya juga memiliki masalah ini, menjalankan futurize 0.17.1 di Python 2.7.16. Contoh ini menggambarkan masalah:

$ echo 'x = 100/10 * 10' | futurize --stage2 -

RefactoringTool: Refactored <stdin>
--- <stdin> (original)
+++ <stdin> (refactored)
@@ -1 +1,3 @@
-x = 100/10 * 10
+from __future__ import division
+from past.utils import old_div
+x = old_div(100,10 * 10)
RefactoringTool: Files that need to be modified:
RefactoringTool: <stdin>

Perhatikan bahwa 100/10 * 10 (==100) dikonversi menjadi old_div(100,10 * 10) (==1). Ini sepertinya bug utama bagi saya.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat