web-dev-qa-db-ja.com

In python 3.xは、python 2(ステートメントとして)のように印刷を機能させます

python 2以前のように、構文をあちこちで変更せずに)print関数を機能させることができるのだろうか。

だから私は次のようなステートメントを持っています:

print "hello world"

そして、私はその構文がpython 3。ライブラリsixをインポートしようとしましたが、うまくいきませんでした(まだ構文エラーです)。

13
paul23

いいえ、あなたがすることはできません。 printステートメントはPython3でなくなりました。コンパイラはそれをサポートしなくなりました。

できますprint()を関数のように機能させますin Python 2;これをprintを使用するすべてのモジュールの先頭に配置します。

_from __future__ import print_function
_

これにより、Python 3でなくなったのと同じように、Python 2のprintステートメントのサポートが削除され、出荷される print()関数を使用できます。 Python 2 を使用します。

sixは、Python2と3の両方を念頭に置いて記述されたコードのブリッジにのみ役立ちます。これには、printステートメントをprint()関数firstに置き換えることが含まれます。

移植Python2コードをPython 3howto ;に読みたいと思うかもしれません。このような_from __future___インポートについても説明し、修正の自動化に役立つ ModernizeFuturize などのツールを紹介します。 Python2コードはPython2と3の両方で機能します。

9
Martijn Pieters

正規表現を使用して、python2の印刷コードをpython3に置き換えることができます。

find:
(print) (.*)(\n)

replace with:
$1($2)$3
5
OliverQ

ツールを使用できます2to3自動Python 2から3のコード変換 、 @ MartijnPieters♦が言ったように:)、古いpythonを投げて、変更をpython 3にすると、簡単にこのような例:

私はこのファイル、python2.pyを作成しました:

#!python3

print 5

pythonで実行すると、明らかに次のように表示されます。

line 3
    print 5          ^
SyntaxError: Missing parentheses in call to 'print'

したがって、次のようにターミナルを介して変換できます。

これは重要なコマンドです

$ 2to3 -w home/path_to_file/python2.py

-wパラメータはファイルを書き込みます。適用せずに将来の変更のみを表示したい場合は、-wなしで実行してください。実行後、次のように表示されます

root: Generating grammar tables from /usr/lib/python2.7/lib2to3/PatternGrammar.txt
RefactoringTool: Refactored Desktop/stackoverflow/goto.py
--- Desktop/stackoverflow/goto.py   (original)
+++ Desktop/stackoverflow/goto.py   (refactored)
@@ -1,3 +1,3 @@
 #!python3

-print 5
+print(5)
RefactoringTool: Files that were modified:

そして、ファイルは次のようになります。

#!python3

print(5)

builtins.__import__をオーバーライドし、単純な正規表現を使用して、親を持たない印刷ステートメントを変換しても問題がない場合は、次の操作を実行できます。これは実際にはファイルを変更しないことに注意してください。ファイルをインポートすると、コードが文字列に読み込まれ、その文字列を微調整してから、修正されたコードがコンパイラ/インポーターに送信されます。

import re
import sys
if sys.version_info >= (3, 0):
  import lib2to3
  from lib2to3 import main, refactor
  import os
  import types
  import builtins
  import sys
  import importlib

  cache = {}

  prevImport = builtins.__import__

  def customImport(path, *args, **kwargs):
    #print (path, args, kwargs)
    try:
      return fimport(path + ".py")
    except:
      return prevImport(path, *args, **kwargs)

  def reload(filename):
    fimport(filename.__file__, forceReload=True)

  def fimport(filename, forceReload=False):
    filename = os.path.abspath(filename)
    modulePath = os.path.splitext(os.path.basename(filename))[0]
    if filename in cache and not forceReload:
      execval, modifyTime, module = cache[filename]
      if modifyTime == os.path.getmtime(filename):
        return module
    f = open(filename)
    text = f.read() + "\n"
    p = re.compile("print")
    res = []
    curI = 0
    for m in p.finditer(text):
      i = m.start()
      res.append(text[curI:i])
      curI = i
      pieceTmp = text[i:].split("\n")[0]
      piece = text[i:].split("\n")[0].split("#")[0]
      pieceAfter = piece[len('print'):].strip()
      if pieceAfter[0] != '(':
        resLine = "print" + "(" + pieceAfter + ")" + "\n"
        res.append(resLine)
      else:
        res.append(pieceTmp)
      curI += len(pieceTmp)+1
    text = "".join(res)
    f.close()
    '''
    # this code can run lib2to3 if you want but just for replacing prints that is not needed
    #fixes = sorted(lib2to3.refactor.get_fixers_from_package('lib2to3.fixes'))
    fixes = ['lib2to3.fixes.fix_print']
    rt = lib2to3.main.StdoutRefactoringTool(fixes, {}, [], False, False)
    res = str(rt.refactor_string(text, name=modulePath))
    '''
    res = text
    res = compile(res, '<string>', 'exec')
    module = types.ModuleType(modulePath)
    module.__file__ = filename
    cache[filename] = (res, os.path.getmtime(filename), module)
    exec(res, module.__dict__)
    return module


  builtins.__import__ = customImport
  importlib.reload = reload

このコードをたとえばpastimport.pyに保存すると、juniper.pyという名前のファイルがあるとします。

def wow(a):
  print a

Python3からjuniper.pyを呼び出したい場合は、次のようにします。

import pastimport
import juniper

juniper.wow("bean")

そしてそれは実行されます:)

これはおそらくより高速で、キャッシュやロギングなどを使用した一般的なインポートに似ている可能性がありますが、pycファイルがいつどのように生成されるかはまだ正確にはわかりません。 cプラグインなどのEdgeケースもあるかもしれません。したがって、自由に改善を提案してください。ただし、少なくともこれは概念実証です。インタープリターの入力と現在のファイルの値を実際に微調整できるはずだと思いますが、今はそれをいじっています。

また、技術的には、これにより任意のpython2ファイル(2to3修正xrange、printなど)をインポートできます。これらのファイルが他のpython2ファイルをインポートすると、誰もが使用するインポートが上書きされるため、それらも変換されます。また、任意の演算子のオーバーロードを実装したり、静的型付けを要求したり、実際には中括弧を要求したり、技術的には他の言語からコードをインポートしたり、この単一のインポートでpython]を変更したりすることもできます。しかし、私は逸脱します。

1
Phylliida