Python コードのリファクタリングRefactoring Python code

Visual Studio には、Python ソース コードの変換とクリーンアップを自動的に実行するためのいくつかのコマンドが用意されています。Visual Studio provides several commands for automatically transforming and cleaning up your Python source code:

<a name="rename-variable"<a name="rename-variable"

名前の変更Rename

  1. 名前を変更する識別子を右クリックして、[名前の変更] を選択します。または、その識別子にキャレットを置き、[編集] > [リファクター] > [名前の変更] メニュー (F2 キー) を選択します。Right-click the identifier you wish to rename and select Rename, or place the caret in that identifier and select the Edit > Refactor > Rename... menu command (F2).
  2. 表示された [名前の変更] ダイアログで、識別子の新しい名前を入力し、[OK] を選択します。In the Rename dialog that appears, enter the new name for the identifier and select OK:

    新しい識別子名を入力するための [名前の変更] プロンプト

  3. その次のダイアログで、名前変更を適用するコード内のファイルとインスタンスを選択します。特定の変更をプレビューするには、個別のインスタンスを選択します。In the next dialog, select the files and instances in your code to which to apply the renaming; select any individual instance to preview the specific change:

    変更の適用場所を選択するための [名前の変更] ダイアログ

  4. [適用] を選択して、ソース コード ファイルを変更します。Select Apply to make the changes to your source code files. (この操作を元に戻すことはできません)。(This action can be undone.)

メソッドの抽出Extract method

  1. 別のメソッドに抽出するコード行または式を選択します。Select the lines of code or the expression to extract into a separate method.
  2. [編集] > [リファクター] > [メソッドの抽出] メニュー コマンドを選択するか、Ctrl + R、M キーを押します。Select the Edit > Refactor > Extract method... menu command or type Ctrl-R, M.
  3. 表示されるダイアログ ボックスで新しいメソッドの名前を入力し、抽出先を指定して、クロージャ変数を選択します。In the dialog that appears, enter a new method name, indicate where to extract it to, and select any closure variables. クロージャに選択されなかった変数はメソッド引数に返されます。Variables not selected for closure are turned into method arguments:

    [メソッドの抽出] ダイアログ

  4. [OK] を選択すると、指定に従ってコードが変更されます。Select OK and the code is modified accordingly:

    メソッドの抽出の効果

インポートの追加Add import

型情報のない識別子にキャレットを置くと、スマート タグ (コードの左側の電球アイコン) が表示され、そのコマンドを使用して必要な import または from ... import ステートメントを追加できます。When you place the caret on an identifier that lacks type information, Visual Studio provides a smart tag (the lightbulb icon to the left of the code) whose commands add the necessary import or from ... import statement:

[インポートの追加] スマート タグ

Visual Studio では、現在のパッケージの最上位のパッケージとモジュール、および標準ライブラリについて import の入力候補を表示できます。Visual Studio offers import completions for top-level packages and modules in the current project and the standard library. また、サブモジュール、サブパッケージ、およびモジュール メンバーについて from ... import の入力候補も表示できます。Visual Studio also offers from ... import completions for submodules and subpackages as well as module members. 入力候補には、関数、クラス、またはエクスポートされたデータが含まれます。Completions include functions, classes, or exported data. いずれかの選択肢を選択すると、そのステートメントがファイル上部の他のインポートの後に追加されるか、同じモジュールが既にインポートされている場合は既存の from ... import ステートメント内に挿入されます。Selecting either option adds the statement to at the top of the file after other imports, or into an existing from ... import statement if the same module is already imported.

インポートの追加の結果

Visual Studio は、モジュール内で実際に定義されていないメンバーを除外しようとします (別のモジュール内にインポートされたが、インポートを行うモジュールの子ではないモジュールなど)。Visual Studio attempts to filter out members that aren't actually defined in a module, such as modules that are imported into another but aren't children of the module doing the importing. たとえば、多くのモジュールが from xyz import sys ではなく import sys を使用するため、モジュールに sys を除外する __all__ メンバーがなくても、他のモジュールから sys をインポートするための入力候補が表示されません。For example, many modules use import sys rather than from xyz import sys, so you don't see a completion for importing sys from other modules even if the modules are missing an __all__ member that excludes sys.

同様に、Visual Studio は他のモジュールまたは組み込みの名前空間からインポートされる関数を除外します。Similarly, Visual Studio filters functions that are imported from other modules or from the built-in namespace. たとえば、あるモジュールが sys モジュールから settrace 関数をインポートする場合、理論的にはそのモジュールから関数をインポートすることもできます。For example if a module imports the settrace function from the sys module, then in theory you could import it from that module. しかし、import settrace from sys を直接使用する方法が最良であるため、Visual Studio はそのステートメントを明確に提示します。But it's best to use import settrace from sys directly, and so Visual Studio offers that statement specifically.

さらに、通常は除外される候補が、(たとえば名前がモジュール内の値に割り当てられているなどの理由で) 表示対象となる他の値を含んでいる場合でも、Visual Studio はそのインポートを除外します。Finally, if something would normally be excluded but has other values that would be included (because the name was assigned a value in the module, for example), Visual Studio still excludes the import. この動作は、その値が別のモジュールで定義されており、追加で割り当てるとエクスポートされないダミーの値になる可能性があるため、その値をエクスポートすべきではないということを前提としています。This behavior assumes that the value shouldn't be exported because it is defined in another module, and thus the additional assignment is likely to be a dummy value that is also not exported.

<a name="remove-imports"<a name="remove-imports"

使用されていないインポートの削除Remove unused imports

コードの作成では、モジュールの import ステートメントが最終的にまったく使われないことがよくあります。When writing code, it's easy to end up with import statements for modules that aren't being used at all. Visual Studio はコードを分析するので、インポートされた名前が import ステートメントの出現箇所より下のスコープ内で使用されているかどうかを調べて、import ステートメントが必要かどうかを自動的に判断できます。Because Visual Studio analyzes your code, it can automatically determine whether an import statement is needed by looking at whether the imported name is used within the scope below where the statement occurs.

エディター内の任意の場所を右クリックして [Remove Imports (インポートの削除)] を選択すると、[すべてのスコープ] または [Current Scope (現在のスコープ)] のいずれかを選択できます。Right-click anywhere in the editor and select Remove Imports, which gives you options to remove from All Scopes or just the Current Scope:

[Remove imports (インポートの削除)] メニュー

Visual Studio によってコードが適切に変更されます。Visual Studio then makes the appropriate changes to the code:

インポートの削除の効果

Visual Studio は制御フローを考慮しないことに注意してください。import ステートメントの前に名前を使用した場合、その名前は実際に使用されたものとして扱われます。Note that Visual Studio does not account for control flow; using a name before an import statement is treated as if the name was in fact used. また、Visual Studio はすべての from __future__ インポート、クラス定義の内部で実行されるインポート、from ... import * ステートメントから実行されるインポートを無視します。Visual Studio also ignores all from __future__ imports, imports that are performed inside of a class definition, as well from from ... import * statements.