プログラミング FAQ

General questions

Is there a source code-level debugger with breakpoints and single-stepping?

はい。

Python 用のデバッガについては次に解説してあり、組み込みの breakpoint() 関数でそれらのデバッガに処理を移せます。

pdb モジュールは簡素にして十分な Python のコンソールモードデバッガです。これは Python の標準ライブラリに含まれているもので、 ライブラリリファレンスマニュアルにドキュメントがあります 。 pdb のコードを手本にして自分用のデバッガを書くこともできます。

The IDLE interactive development environment, which is part of the standard Python distribution (normally available as idlelib), includes a graphical debugger.

PythonWin は、pdb をベースとした GUI デバッガを含む Python IDE です。Pythonwin デバッガは、ブレークポイントの色付けや非 PythonWin プログラムのデバッグなどの素敵な機能をたくさん持っています。PythonWin は pywin32 プロジェクトの一部、あるいは ActivePython ディストリビューションの一部として利用可能です。

Eric は PyQt や Scintilla editing component をもとにした IDE です。

trepan3k は gdbライクなデバッガです。

Visual Studio Code はバージョン管理ソフトと一緒になったデバッグツールを備えた IDE です

商業のグラフィカルデバッガ付き Python IDE もあります。例えば:

バグの発見や静的解析に役立つツールはありますか?

はい。

Ruff, Pylint and Pyflakes do basic checking that will help you catch bugs sooner.

Static type checkers such as mypy, ty, Pyrefly, and pytype can check type hints in Python source code.

どうしたら Python スクリプトからスタンドアロンバイナリを作れますか?

ユーザがダウンロードでき、Python ディストリビューションをインストールせずに実行できるようなスタンドアロンプログラムだけでいいなら、Python を C コードにコンパイルできなくても構いません。プログラムに対して必要なモジュールを選び、そのモジュールを Python バイナリに束縛して一つの実行可能ファイルにまとめる多くのツールがあります。

One is to use the freeze tool, which is included in the Python source tree as Tools/freeze. It converts Python byte code to C arrays; with a C compiler you can embed all your modules into a new program, which is then linked with the standard Python modules.

これはあなたのソースの (両方の形式の) import 文を再帰的にスキャンし、import されたモジュールを標準の Python パスと (組み込みモジュールのある) ソースディレクトリから探します。そして Python で書かれたモジュールのバイトコードを C コード (marshal モジュールでコードオブジェクトに変換できる配列) に変換し、実際にそのプログラム内で使われている組み込みモジュールだけが含まれたカスタムメイドの設定ファイルを作成します。そして生成された C コードをコンパイルして Python インタプリタの残りとリンクし、元のスクリプトと全く同じように動作する自己完結的なバイナリを形成します。

以下のパッケージはコンソールやGUIの実行ファイル作成に役立ちます。

Python プログラムのためのコーディングスタンダードやスタイルガイドはありますか?

はい。標準ライブラリモジュールに求められるコーディングスタイルは PEP 8 として文書化されています。

Core language

なぜ変数に値があるのに UnboundLocalError が出るのですか?

もともと動いていたコードが、関数の本体のどこかに代入文を加えるという変更をしたら UnboundLocalError を出すのには驚くかもしれません。

このコード:

>>> x = 10
>>> def bar():
...     print(x)
...
>>> bar()
10

は動きますが、このコード:

>>> x = 10
>>> def foo():
...     print(x)
...     x += 1

UnboundLocalError になります:

>>> foo()
Traceback (most recent call last):
  ...
UnboundLocalError: cannot access local variable 'x' where it is not associated with a value

これは、あるスコープの中で変数に代入を行うとき、その変数はそのスコープに対してローカルになり、外のスコープにある同じ名前の変数を隠すからです。foo の最後の文が x に新しい値を代入しているので、コンパイラはこれをローカル変数であると認識します。その結果、先の print(x) が初期化されていないローカル変数を表示しようとして結果はエラーとなります。

上の例では、グローバルであると宣言することで外のスコープにアクセスできます:

>>> x = 10
>>> def foobar():
...     global x
...     print(x)
...     x += 1
...
>>> foobar()
10

この明示的な宣言は (表面的には似ているクラスとインスタンス変数の例とは違って) あなたは実際は他のスコープの変数の値を変えようとしているのだ、ということを知らせるのに必要です:

>>> print(x)
11

同様のことを、ネストされたスコープで nonlocal 予約語を使うことでもできます:

>>> def foo():
...    x = 10
...    def bar():
...        nonlocal x
...        print(x)
...        x += 1
...    bar()
...    print(x)
...
>>> foo()
10
11

Python のローカルとグローバル変数のルールは何ですか?

Python では、関数内で参照されるだけの変数は暗黙的にグローバルとなります。 関数の本体のどこかで値が変数に代入されたなら、それは明示的にグローバルであると宣言されない限り、ローカルであるとみなされます。

最初はちょっと驚くでしょうが、少し考えると納得できます。一方では、代入された変数に global を要求することで、意図しない副作用を防げます。他方では、グローバルな参照の度に global が要求されてしまうと、 global を使ってばかりになってしまいます。ビルトイン関数やインポートされたモジュールの内容を参照するたびにグローバル宣言をしなければならないのです。その乱雑さは副作用を特定するための global 宣言の便利さよりも重大です。

ループの中で異なる値で定義されたラムダ式が、同じ値を返すのはなぜですか?

Assume you use a for loop to define a few different lambdas (or even plain functions), for example:

>>> squares = []
>>> for x in range(5):
...     squares.append(lambda: x**2)

これで x**2 を計算する 5 つのラムダのリストが得られます。それらを呼び出したとき、それぞれ 014916 を返すと予想するかもしれません。しかし実際にやってみると、全て 16 が返ってくるのを目にするでしょう:

>>> squares[2]()
16
>>> squares[4]()
16

This happens because x is not local to the lambdas, but is defined in the outer scope, and it is accessed when the lambda is called --- not when it is defined. At the end of the loop, the value of x is 4, so all the functions now return 4**2, that is 16. You can also verify this by changing the value of x and see how the results of the lambdas change:

>>> x = 8
>>> squares[2]()
64

これを避けるためには、グローバルの x の値に依存しないために、ラムダにとってのローカル変数に値を保存する必要があります:

>>> squares = []
>>> for x in range(5):
...     squares.append(lambda n=x: n**2)

ここで、n=x は新しいラムダにとってのローカル変数 n を作成し、ラムダが定義されるときに計算されるので、ループのその時点での x と同じ値を持っています。これは、1 つ目のラムダでは n の値は 0 になり、2 つ目では 1、3 つ目では 2 以下同様、となることを意味します。従って、それぞれのラムダは今や正しい値を返すようになりました:

>>> squares[2]()
4
>>> squares[4]()
16

この動作はラムダに特有なものではなく、通常の関数にも適用されることに注意してください。

グローバル変数をモジュール間で共有するにはどうしたらいいですか?

一つのプログラムのモジュール間で情報を共有する正準な方法は、特別なモジュール (しばしば config や cfg と呼ばれる) を作ることです。単に設定モジュールをアプリケーションのすべてのモジュールにインポートしてください。このモジュールはグローバルな名前として使えます。それぞれのモジュールのただ一つのインスタンスがあるので、設定モジュールオブジェクトに対するいかなる変更も全体に反映されます。例えば:

config.py:

x = 0   # Default value of the 'x' configuration setting

mod.py:

import config
config.x = 1

main.py:

import config
import mod
print(config.x)

なお、同じ理由から、モジュールを使うということは、シングルトンデザインパターンを実装することの基礎でもあります。

モジュールで import を使う際の「ベストプラクティス」は何ですか?

一般的に from modulename import * を使ってはいけません。そのようにするとインポータの名前空間は汚染され、linter が未定義の名前を発見することが難しくなります。

モジュールはファイルの先頭でインポートしてください。これによってコードが必要とする他のモジュールが明確になり、モジュール名がスコープに含まれるかどうかに迷わなくなります。行に一つのインポートにすると、モジュールのインポートの追加と削除が容易になりますが、行に複数のインポートにすると画面の領域が少なく済みます。

次の手順でモジュールをインポートするのが、良い習慣になります:

  1. standard library modules -- such as sys, os, argparse, re

  2. third-party library modules (anything installed in Python's site-packages directory) -- such as dateutil, requests, tzdata

  3. 自前で開発したモジュール

循環参照の問題を避けるために、インポートを関数やクラスに移すことが必要なときもあります。Gordon McMillan によれば:

循環参照は両方のモジュールが "import <module>" 形式のインポートを使っていれば大丈夫です。二つ目のモジュールが最初のモジュールから名前を確保しようとして ("from module import name")、そのインポートがトップレベルにあると駄目です。最初のモジュールが二つ目のモジュールをインポートするのに忙しくて、最初のモジュールの名前が利用可能になっていないからです。

この状況では、二つ目のモジュールが一つの関数の中でのみ使われているならば、そのインポートは簡単に関数の中に移せます。インポートが呼ばれたとき、最初のモジュールは初期化を完了していて、二つ目のモジュールは自分のインポートをできます。

プラットフォーム依存のモジュールがあるときには、インポートをトップレベルの外に動かすことも必要です。この場合、ファイルの先頭ではすべてのモジュールをインポートすることさえできないかもしれません。この場合は、対応するプラットフォームに合わせたコードで正しいモジュールをインポートすることを選ぶと良いです。

循環参照の問題を避けたりモジュールの初期化にかかる時間を減らしたりしたいなら、単にインポートを関数定義の中などのローカルなスコープに移してください。この手法は多くのインポートがプログラムがどのように実行されるかに依存しなくてよいときに特に有効です。ある関数の中でのみモジュールが使われるのなら、インポートをその関数の中に移すことを考えてもいいでしょう。なお、モジュールを読み込む最初の回はモジュールの初期化の時間のために高価になりえますが、複数回目にモジュールを読み込むのは事実上無料、辞書探索の数回のコストだけで済みます。モジュール名がスコープから外れてさえ、そのモジュールはおそらく sys.modules から利用できるでしょう。

なぜオブジェクト間でデフォルト値が共有されるのですか?

この種のバグがよく初心者プログラマに噛み付きます。この関数を考えてみてください:

def foo(mydict={}):  # Danger: shared reference to one dict for all calls
    ... compute something ...
    mydict[key] = value
    return mydict

初めてこの関数を呼び出した時、mydict には一つの要素があります。二回目には、foo() が実行されるときに mydict には初めから一つの要素をすでに持っているので、mydict には二つの要素があります。

関数の呼び出しによって、デフォルトの値に対する新しいオブジェクトが作られるのだと予想しがちです。実はそうなりません。デフォルト値は、関数が定義されたときに一度だけ生成されます。この例の辞書のように、そのオブジェクトが変更されたとき、その後の関数の呼び出しは変更後のオブジェクトを参照します。

定義の時に、数、文字列、タプル、None など、イミュータブルなオブジェクトを使うと変更される危険がありません。辞書、リスト、クラスインスタンスなどのミュータブルなオブジェクトは混乱のもとです。

この性質から、ミュータブルなオブジェクトをデフォルト値として使わないプログラミング手法がいいです。代わりに、None をデフォルト値に使い、そのパラメタが None である時にだけ、関数の内部で新しいリスト/辞書/その他をつくるようにしてください。例えば、こう書かずに:

def foo(mydict={}):
    ...

代わりに:

def foo(mydict=None):
    if mydict is None:
        mydict = {}  # create a new dict for local namespace

この性質が便利なこともあります。時間のかかる計算を行う関数があるときに使われる一般的な技法は、関数が呼び出されるごとにパラメタと結果の値をキャッシュし、再び同じ値が要求されたらキャッシュされた値を返すというものです。これは "memoizing" と呼ばれ、このように実装されます:

# Callers can only provide two parameters and optionally pass _cache by keyword
def expensive(arg1, arg2, *, _cache={}):
    if (arg1, arg2) in _cache:
        return _cache[(arg1, arg2)]

    # Calculate the value
    result = ... expensive computation ...
    _cache[(arg1, arg2)] = result           # Store result in the cache
    return result

デフォルト値の代わりに、辞書を含むグローバル変数も使えます。これは好みの問題です。

オプションパラメータやキーワードパラメータを関数から関数へ渡すにはどうしたらいいですか?

関数のパラメータリストに引数を *** 指定子 (specifier) で集めてください。そうすれば、位置引数をタプルとして、キーワード引数を辞書として得られます。これで、他の関数を呼び出すときに *** を使ってそれらの引数を渡せます:

def f(x, *args, **kwargs):
    ...
    kwargs['width'] = '14.3c'
    ...
    g(x, *args, **kwargs)

実引数と仮引数の違いは何ですか?

仮引数 (parameter) は関数定義に表れる名前で定義されるのに対し、 実引数 (argument) は関数を呼び出すときに実際に渡す値のことです。仮引数は関数が受け取ることの出来る 実引数の型 を定義します。例えば、以下のような関数定義があったとして:

def func(foo, bar=None, **kwargs):
    pass

foobarkwargsfunc の仮引数です。一方、func を呼び出すときには、例えば:

func(42, bar=314, extra=somevar)

42314somevar という値は実引数です。

なぜ list 'y' を変更すると list 'x' も変更されるのですか?

次のようなコードを書いたとします:

>>> x = []
>>> y = x
>>> y.append(10)
>>> y
[10]
>>> x
[10]

どうして y への要素の追加が x も変更してしまうのか疑問に思うかもしれません。

このような結果になる2つの要因があります:

  1. 変数とは、単にオブジェクトを参照するための名前に過ぎません。 y = x とすることは、リストのコピーを作りません -- それは x が参照するのと同じオブジェクトを参照する新しい変数 y を作ります。つまり、あるのは一つのオブジェクト(この場合リスト)だけであって、 xy の両方がそれを参照しているのです。

  2. リストは mutable です。内容を変更出来る、ということです。

After the call to append(), the content of the mutable object has changed from [] to [10]. Since both the variables refer to the same object, using either name accesses the modified value [10].

代わりに x にイミュータブルを代入すると:

>>> x = 5  # ints are immutable
>>> y = x
>>> x = x + 1  # 5 can't be mutated, we are creating a new object here
>>> x
6
>>> y
5

この場合ご覧の通り xy はまったく同じではありませんね。これは整数が immutable だからで、 x = x + 1 は整数の 5 の値を変更しているのではありません; 代わりに新しいオブジェクト(整数 6)を作って x に代入しています (つまり x が参照するオブジェクトが変わります)。この代入の後では私たちは 2 つのオブジェクト(整数の 65)を持っていて、2 つの変数はそれらを参照しています(x はいまや 6 を参照していますが y5 を参照したままです)。

ある演算 (たとえば y.append(10), y.sort()) がオブジェクトを変更する一方で、外見上は似た演算 (たとえば y = y + [10], sorted(y)) は新しいオブジェクトを作ります。Python では一般に (そして標準ライブラリの全てのケースで)、このような 2 つのタイプの演算にまつわる混乱を避けるために、オブジェクトを変更するメソッドは None を返します。ですからもしあなたが誤って y の複製の並び替えをするつもりで y.sort() と書いた場合に結果手にするのは None でしょうから、あなたのプログラムは簡単に診断出来るエラーを起こすでしょう。

しかしながら、同じ操作が型ごとに異なる振る舞いをする演算の種類が一つあります: 累算代入演算です。例えば += はリストを変更しますが、タプルや整数は変更しません(a_list += [1, 2, 3]a_list.extend([1, 2, 3]) と同じ意味で、そして a_list を変更しますが、 some_tuple += (1, 2, 3)some_int += 1 は新しいオブジェクトを作ります)。

言い換えると:

  • If we have a mutable object (such as list, dict, set), we can use some specific operations to mutate it and all the variables that refer to it will see the change.

  • If we have an immutable object (such as str, int, tuple), all the variables that refer to it will always see the same value, but operations that transform that value into a new value always return a new object.

2つの変数が同じオブジェクトを参照しているかどうかが知りたければ、 is 演算子や組み込み関数 id() が使えます。

出力引数のある関数 (参照渡し) はどのように書きますか?

Remember that arguments are passed by assignment in Python. Since assignment just creates references to objects, there's no alias between an argument name in the caller and callee, and consequently no call-by-reference. You can achieve the desired effect in a number of ways.

  1. 結果のタプルを返すことによって:

    >>> def func1(a, b):
    ...     a = 'new-value'        # a and b are local names
    ...     b = b + 1              # assigned to new objects
    ...     return a, b            # return new values
    ...
    >>> x, y = 'old-value', 99
    >>> func1(x, y)
    ('new-value', 100)
    

    これはたいてい一番明確な方法です。

  2. グローバル変数を使って。これはスレッドセーフでないので、推奨されません。

  3. ミュータブルな (インプレースに変更可能な) オブジェクトを渡すことによって:

    >>> def func2(a):
    ...     a[0] = 'new-value'     # 'a' references a mutable list
    ...     a[1] = a[1] + 1        # changes a shared object
    ...
    >>> args = ['old-value', 99]
    >>> func2(args)
    >>> args
    ['new-value', 100]
    
  4. 変更される辞書に渡すことによって:

    >>> def func3(args):
    ...     args['a'] = 'new-value'     # args is a mutable dictionary
    ...     args['b'] = args['b'] + 1   # change it in-place
    ...
    >>> args = {'a': 'old-value', 'b': 99}
    >>> func3(args)
    >>> args
    {'a': 'new-value', 'b': 100}
    
  5. または、クラスインスタンスに値を同梱することによって:

    >>> class Namespace:
    ...     def __init__(self, /, **args):
    ...         for key, value in args.items():
    ...             setattr(self, key, value)
    ...
    >>> def func4(args):
    ...     args.a = 'new-value'        # args is a mutable Namespace
    ...     args.b = args.b + 1         # change object in-place
    ...
    >>> args = Namespace(a='old-value', b=99)
    >>> func4(args)
    >>> vars(args)
    {'a': 'new-value', 'b': 100}
    

    このような複雑なことをする理由はめったに無いでしょう。

一番の選択は、複数の結果を含むタプルを返すことです。

Python で高次関数はどのようにつくりますか?

二つの方法があります: ネストされたスコープを使う方法と、呼び出し可能オブジェクトを使う方法です。例えば、a*x+b の値を計算する f(x) 関数を返す linear(a,b) を定義したいとします。ネストされたスコープを使うと:

def linear(a, b):
    def result(x):
        return a * x + b
    return result

また、呼び出し可能オブジェクトを使うと:

class linear:

    def __init__(self, a, b):
        self.a, self.b = a, b

    def __call__(self, x):
        return self.a * x + self.b

どちらの場合でも、

taxes = linear(0.3, 2)

とすれば、taxes(10e6) == 0.3 * 10e6 + 2 となるような呼び出し可能オブジェクトを得られます。

呼び出し可能オブジェクトを使う方法は、少し遅くなり、わずかにコードが長くなるという短所があります。ですが、継承を使って呼び出し可能オブジェクト同士で記号を共有することもできます:

class exponential(linear):
    # __init__ inherited
    def __call__(self, x):
        return self.a * (x ** self.b)

オブジェクトはいくつかのメソッドに状態をカプセル化できます:

class counter:

    value = 0

    def set(self, x):
        self.value = x

    def up(self):
        self.value = self.value + 1

    def down(self):
        self.value = self.value - 1

count = counter()
inc, dec, reset = count.up, count.down, count.set

ここで、inc()dec()reset() は同じカウント変数を共有する関数のようにふるまいます。

Python のオブジェクトはどのようにコピーしますか?

一般的に、普通は copy.copy()copy.deepcopy() を試してください。何でもコピーできるとは限りませんが、たいていはできます。

もっと簡単にコピーできるオブジェクトもあります。辞書には copy() メソッドがあります:

newdict = olddict.copy()

シーケンスはスライシングでコピーできます:

new_l = l[:]

オブジェクトのメソッドや属性はどのように見つけますか?

ユーザー定義クラスのインスタンス x で、dir(x),< はインスタンス属性とそのクラスで定義されたメソッドや属性を含む名前のアルファベット順リストを返します。

コードはどのようにオブジェクトの名前を見つけるのですか?

概して、オブジェクトは本当は名前を持たないので、見つけることはできません。本質的には、代入とはいつも値に名前を束縛することです。defclass 文も同じですが、この場合は値はコーラブルです。以下のコードを考えてみましょう:

>>> class A:
...     pass
...
>>> B = A
>>> a = B()
>>> b = a
>>> print(b)
<__main__.A object at 0x16D07CC>
>>> print(a)
<__main__.A object at 0x16D07CC>

おそらく、このクラスには名前があります。このクラスは二つの名前に縛られて、名前 B を通して呼び出されますが、それでもクラス A のインスタンスとして報告されるのです。しかし、両方の名前が同じ値に束縛されている以上、このインスタンスの名前が ab か決めることはできないのです。

概して、コードにとってある値の「名前を知っている」事は重要ではありません。あなたがわざと内省的なコードを書いているのでない限り、方針を変えた方がいいかもしれないということになるでしょう。

comp.lang.python で、Fredrik Lundh はこの問題の答えとして素晴らしい喩えをしてくれました:

玄関にいた猫の名前を知るのと同じ方法です: その猫 (オブジェクト) 自体はその名前を言うことができないし、それは実は問題ではありません -- その猫が何と呼ばれているかを知る唯一の方法は、すべての隣人 (名前空間) にその猫 (オブジェクト) が何と呼ばれているかを聞くことです。

……そして、その猫が沢山の名前で知られていたり、逆に全く名前が無かったりしても驚かないでください!

カンマ演算子はなぜ優先されるのですか?

カンマは Python では演算子ではありません。このセッションを考えてください:

>>> "a" in "b", "a"
(False, 'a')

カンマは演算子ではなく、式の分離子なので、上の式は次の式と同じように評価されます:

("a" in "b"), "a"

こうではありません:

"a" in ("b", "a")

The same is true of the various assignment operators (=, +=, and so on). They are not truly operators but syntactic delimiters in assignment statements.

C の "?:" 三項演算子と等価なものはありますか?

はい、あります。構文は以下のようになります:

[on_true] if [expression] else [on_false]

x, y = 50, 25
small = x if x < y else y

この構文が導入された 2.5 以前のバージョンに関しては、論理演算子を使ったこのイディオムが一般的でした:

[expression] and [on_true] or [on_false]

しかし、このイディオムは安全ではありません。on_true のブール値が偽であるときに間違った結果を与えることがあります。ですから、いつでも ... if ... else ... 形式を使ったほうが良いです。

Python で解し難いワンライナーを書くことはできますか?

はい。そういうものはたいてい、 lambda の中に lambda がネストされています。Ulf Bartelt によるものを少しアレンジした下の3つの例を見てください:

from functools import reduce

# Primes < 1000
print(list(filter(None,map(lambda y:y*reduce(lambda x,y:x*y!=0,
map(lambda x,y=y:y%x,range(2,int(pow(y,0.5)+1))),1),range(2,1000)))))

# First 10 Fibonacci numbers
print(list(map(lambda x,f=lambda x,f:(f(x-1,f)+f(x-2,f)) if x>1 else 1:
f(x,f), range(10))))

# Mandelbrot set
print((lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+'\n'+y,map(lambda y,
Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,Sy=Sy,L=lambda yc,Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,i=IM,
Sx=Sx,Sy=Sy:reduce(lambda x,y:x+y,map(lambda x,xc=Ru,yc=yc,Ru=Ru,Ro=Ro,
i=i,Sx=Sx,F=lambda xc,yc,x,y,k,f=lambda xc,yc,x,y,k,f:(k<=0)or (x*x+y*y
>=4.0) or 1+f(xc,yc,x*x-y*y+xc,2.0*x*y+yc,k-1,f):f(xc,yc,x,y,k,f):chr(
64+F(Ru+x*(Ro-Ru)/Sx,yc,0,0,i)),range(Sx))):L(Iu+y*(Io-Iu)/Sy),range(Sy
))))(-2.1, 0.7, -1.2, 1.2, 30, 80, 24))
#    \___ ___/  \___ ___/  |   |   |__ lines on screen
#        V          V      |   |______ columns on screen
#        |          |      |__________ maximum of "iterations"
#        |          |_________________ range on y axis
#        |____________________________ range on x axis

よい子はまねしないでね!

関数の引数リストにあるスラッシュ (/) は何を意味しますか?

パラメータ関数の仮引数にあるスラッシュは、それより前にある仮引数は位置専用引数であることを示します。 位置専用引数は、外で使える名前を持たない仮引数です。 位置専用引数を受け付ける関数の呼び出しにおいて、実引数はその位置だけに基づいて仮引数に対応付けられます。 例えば、 divmod() は位置専用引数を受け付けます。 そのドキュメントは次のようになります:

>>> help(divmod)
Help on built-in function divmod in module builtins:

divmod(x, y, /)
    Return the tuple (x//y, x%y).  Invariant: div*y + mod == x.

この引数リストの末尾にスラッシュは、この2つの仮引数が両方とも位置専用引数であることを意味します。 したがって、divmod() をキーワード引数を使って呼び出すとエラーになります:

>>> divmod(x=3, y=4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: divmod() takes no keyword arguments

数と文字列

十六進数や八進数を指定するにはどうしたらいいですか?

八進数を指定するには、八進数での値の先頭に 0 と "o" (小文字または大文字) を加えてください。たとえば、変数 "a" に八進数での "10" (十進数での"8") を代入するには、こう打ってください:

>>> a = 0o10
>>> a
8

十六進数も簡単です。ただ十六進数での値の先頭に 0 と "x" (小文字または大文字) を加えてください。十六進数は小文字でも大文字でも指定できます。たとえば、Python インタプリタで:

>>> a = 0xa5
>>> a
165
>>> b = 0XB2
>>> b
178

なぜ -22 // 10 は -3 を返すのですか?

i % jj と同じ符号であってほしいことに基づいています。それに加えて以下のようにもしたいとすると:

i == (i // j) * j + (i % j)

整数除算は床を返すことになります。C にも C の一貫性があって、i % ji と同じ符号を持つように i // j を丸めています。

i % j は、j が負の時には実際にはほとんど使いません。j が正なら、たくさん使います。その事実上すべての場合、i % j>= 0 となる方が便利です。時計が 10 時を指している時、その 200 時間前は何時でしょうか。-190 % 12 == 2 となるのが便利です。-190 % 12 == -10 は噛み付きかねないバグです。

どうすれば SyntaxError を起こさずに整数リテラルの属性を得られますか?

ふつうの方法で int リテラルの属性を探そうとすると、ピリオドが小数点とみなされ、SyntaxError となります:

>>> 1.__class__
  File "<stdin>", line 1
  1.__class__
   ^
SyntaxError: invalid decimal literal

解決策は、リテラルとピリオドを スペースや括弧で分けることです。

>>> 1 .__class__
<class 'int'>
>>> (1).__class__
<class 'int'>

文字列を数に変換するにはどうしたらいいですか?

For integers, use the built-in int() type constructor, for example, int('144') == 144. Similarly, float() converts to a floating-point number, for example, float('144') == 144.0.

デフォルトでは、これらは数を十進数として解釈するので、 int('0144') == 144 は成立しますが int('0x144')ValueError を送出します。 int(string, base) はオプションの第二引数をとって変換元の基数にします。つまり int( '0x144', 16) == 324 です。基数が 0 と指定された場合、その数は Python の基準によって解釈されます。先頭が '0o' なら八進数で、'0x' なら十六進数を表します。

文字列を数に変換するだけのために eval() を使わないでください。 eval() は特に遅いですし、セキュリティ上のリスクもあります。求められない副作用を持つような Python の式を渡そうとする人がいるかも知れません。例えば、あなたのホームディレクトリを消去する __import__('os').system("rm -rf $HOME") を渡そうとする人がいるかも知れません。

eval() also has the effect of interpreting numbers as Python expressions, so that, for example, eval('09') gives a syntax error because Python does not allow leading '0' in a decimal number (except '0').

数を文字列に変換するにはどうしたらいいですか?

For example, to convert the number 144 to the string '144', use the built-in type constructor str(). If you want a hexadecimal or octal representation, use the built-in functions hex() or oct(). For fancy formatting, see the f-strings and 書式指定文字列の文法 sections. For example, "{:04d}".format(144) yields '0144' and "{:.3f}".format(1.0/3.0) yields '0.333'.

文字列をインプレースに変更するにはどうしたらいいですか?

You can't, because strings are immutable. In most situations, you should simply construct a new string from the various parts you want to assemble it from. However, if you need an object with the ability to modify in-place Unicode data, try using an io.StringIO object or the array module:

>>> import io
>>> s = "Hello, world"
>>> sio = io.StringIO(s)
>>> sio.getvalue()
'Hello, world'
>>> sio.seek(7)
7
>>> sio.write("there!")
6
>>> sio.getvalue()
'Hello, there!'

>>> import array
>>> a = array.array('w', s)
>>> print(a)
array('w', 'Hello, world')
>>> a[0] = 'y'
>>> print(a)
array('w', 'yello, world')
>>> a.tounicode()
'yello, world'

関数やメソッドを呼ぶのに文字列を使うにはどうしたらいいですか?

様々なテクニックがあります。

  • 一番いいのは、文字列を関数に対応させる辞書を使うことです。このテクニックの一番の利点は、文字列が関数の名前と同じ必要がないことです。この方法は case 構造をエミュレートするための一番のテクニックでもあります:

    def a():
        pass
    
    def b():
        pass
    
    dispatch = {'go': a, 'stop': b}  # Note lack of parens for funcs
    
    dispatch[get_input()]()  # Note trailing parens to call function
    
  • 組み込み関数の getattr() を使う方法:

    import foo
    getattr(foo, 'bar')()
    

    なお、 getattr() はクラス、クラスインスタンス、モジュールなど、どんなオブジェクトにも使えます。

    これは標準ライブラリでも何箇所か使われています。このように:

    class Foo:
        def do_foo(self):
            ...
    
        def do_bar(self):
            ...
    
    f = getattr(foo_instance, 'do_' + opname)
    f()
    
  • locals() を使って関数名を決める方法:

    def myFunc():
        print("hello")
    
    fname = "myFunc"
    
    f = locals()[fname]
    f()
    

Is there an equivalent to Perl's chomp() for removing trailing newlines from strings?

S.rstrip("\r\n") を使って文字列 S の終端から他の空白文字を取り除くことなくすべての行末記号を取り除くことができます。文字列 S が複数行を表し、終端に空行があるとき、そのすべての空行も取り除かれます:

>>> lines = ("line 1 \r\n"
...          "\r\n"
...          "\r\n")
>>> lines.rstrip("\n\r")
'line 1 '

これは典型的に一度に一行ずつテキストを読みたい時にのみ使われるので、S.rstrip() をこの方法で使うとうまくいきます。

Is there a scanf() or sscanf() equivalent?

そのようなものはありません。

For simple input parsing, the easiest approach is usually to split the line into whitespace-delimited words using the split() method of string objects and then convert decimal strings to numeric values using int() or float(). split() supports an optional "sep" parameter which is useful if the line uses something other than whitespace as a separator.

もっと複雑な入力解析をしたいなら、C の sscanf よりも正規表現の方が便利ですし、この処理に向いています。

What does UnicodeDecodeError or UnicodeEncodeError error mean?

Unicode HOWTO を参照して下さい。

raw string を奇数個のバックスラッシュで終えることはできますか?

奇数個のバックスラッシュで終わる raw string は文字列のクォートをエスケープします:

>>> r'C:\this\will\not\work\'
  File "<stdin>", line 1
    r'C:\this\will\not\work\'
    ^
SyntaxError: unterminated string literal (detected at line 1)

これにはいくつかの回避策があります。ひとつは通常文字列と二重バックスラッシュを使うことです:

>>> 'C:\\this\\will\\work\\'
'C:\\this\\will\\work\\'

もうひとつは、エスケープされたバックスラッシュを含む通常の文字列を、 raw string に連結します:

>>> r'C:\this\will\work' '\\'
'C:\\this\\will\\work\\'

Windowsでは、 os.path.join() を使ってバックスラッシュを追加することもできます:

>>> os.path.join(r'C:\this\will\work', '')
'C:\\this\\will\\work\\'

注意点として、バックスラッシュは raw string 終端のクォートを「エスケープ」しますが、 raw string の値を解釈する際にはエスケープが生じません。つまり、バックスラッシュは raw string 値の中に残ったままになります:

>>> r'backslash\'preserved'
"backslash\\'preserved"

言語リファレンス の仕様も参照してください。

性能

プログラムが遅すぎます。どうしたら速くなりますか?

That's a tough one, in general. First, here is a list of things to remember before diving further:

  • 性能の傾向は Python 実装によって変わります。この FAQ では CPython に焦点を当てます。

  • 振る舞いはオペレーティングシステムによって変わりえます。特に、I/O やマルチスレッドに関しては顕著です。

  • 常に、コードの最適化を始める 前に プログラムのホットスポットを見つけるべきです (profile モジュールを参照してください)。

  • ベンチマークスクリプトを書くことで、改善箇所の捜索を素早く繰り返せます (timeit モジュールを参照してください)。

  • 洗練された最適化に隠れたリグレッションの可能性を生む前に、(ユニットテストやその他の技法で) コードカバレッジを上げることを強く推奨します。

とは言っても、Python コードを高速化する技法はたくさんあります。ここでは、満足な性能のレベルにたどり着くまでの長い道のりを進む、一般的な方針を示します:

  • コード中に細かい最適化の技法をばらまこうとするよりも、アルゴリズムを高速化 (または高速なアルゴリズムに変更) するほうが、大きな利益を生むことがあります。

  • 適切なデータ構造を使ってください。組み込み型collections を調べてください。

  • 何かをするための基本要素が標準ライブラリにあるなら、自分で発明した代用品よりもそちらのほうが、(絶対にとは言えませんが) おそらく速いです。 それが組み込み型やある種の拡張型のように C で書かれたものならなおさらです。 たとえば、ソートするには、必ず list.sort() 組み込みメソッドか sorted() 関数を使ってください (また、中程度に高度な例は、 ソートのテクニック を参照してください)。

  • 抽象化は、遠回りにしがちで、インタプリタの作業を増やすことになります。この遠回りさが、なされる作業の量より重大になると、プログラムが遅くなってしまいます。過度な抽象化、特に細かい関数やメソッドの形で現れるもの (これは読みにくさも落とします) は防ぐべきです。

pure Python にできる限界に達したなら、更に進むためのツールがあります。例えば、Cython は、Python コードのわずかに変形した版を C 拡張にコンパイルし、多種のプラットフォームで使えます。Cython は、コンパイル (と任意の型アノテーション) を利用し、コードの解釈を大幅に速くします。C プログラミングに自信があるなら、自分で write a C extension module こともできます。

参考

パフォーマンス tips が載っている wiki のページ。

多くの文字列を結合するのに最も効率的な方法は何ですか?

str および bytes オブジェクトはイミュータブルなので、多くの文字列の結合は結合ごとに新しいオブジェクトを作成し、効率が悪いです。 一般的に、全体の実行時間のコストは文字列の長さの二乗に比例します。

多くの str オブジェクトを累積するのにおすすめのイディオムは、すべてをリストに配置してから最後に str.join() を呼び出すことです:

chunks = []
for s in my_strings:
    chunks.append(s)
result = ''.join(chunks)

(Another reasonably efficient idiom is to use io.StringIO.)

多くの bytes オブジェクトを累積するのにおすすめのイディオムは、 bytearray オブジェクトをインプレース結合 (+= 演算子) で拡張することです:

result = bytearray()
for b in my_bytes_objects:
    result += b

Sequences (tuples/lists)

タプル、リスト間の変更はどのようにするのですか?

型コンストラクタ tuple(seq) はすべてのシーケンス (実際には、すべてのイテラブル) を同じ要素、同じ順序のタプルに変換します。

例えば、 tuple([1, 2, 3])(1, 2, 3) を与え、 tuple('abc')('a', 'b', 'c') を与えます。引数がタプルなら、コピーを作らずに引数のオブジェクトそのものを返すので、あるオブジェクトが既にタプルになっているか確信が持てないのなら、 tuple() を呼ぶのが手軽です。

型コンストラクタ list(seq) はすべてのシーケンスあるいはイテラブルを同じ要素、同じ順序のリストに変換します。例えば、list((1, 2, 3))[1, 2, 3] を与え、list('abc')['a', 'b', 'c'] を与えます。引数がリストなら、seq[:] と同様にコピーを作ります。

負の添え字は何ですか?

Python のシーケンスは正の数と負の数でインデクスされます。正の数では、0 が最初のインデクス、1 が 2 番目のインデクス、以下も同様です。負のインデクスでは、-1 が最後のインデクス、-2 が最後から 2 番目のインデクス、以下も同様です。seq[-n]seq[len(seq)-n] と同じだと考えてください。

負のインデクスを使うと便利なことがあります。例えば、S[:-1] は文字列の最後以外のすべての文字を表すので、文字列の末尾の改行を取り除くときに便利です。

シーケンスを逆順にイテレートするにはどうしたらいいですか?

組み込み関数 reversed() を使ってください。

for x in reversed(sequence):
    ...  # do something with x ...

これは元のシーケンスをいじるのではなく、逆順の新しいコピーを作ってイテレートさせます。

リストから重複を取り除くにはどうしますか?

Python Cookbook の長い議論に多くの方法があるので参照してください:

リストを並び替えて構わないのなら、ソートした上でリストの最初から最後までを調べ、次のように重複を削除してください:

if mylist:
    mylist.sort()
    last = mylist[-1]
    for i in range(len(mylist)-2, -1, -1):
        if last == mylist[i]:
            del mylist[i]
        else:
            last = mylist[i]

If all elements of the list may be used as set keys (that is, they are all hashable) this is often faster:

mylist = list(set(mylist))

リストを集合に変換するときに重複は取り除かれるので、それをリストに戻せばいいのです。

How do you remove multiple items from a list?

As with removing duplicates, explicitly iterating in reverse with a delete condition is one possibility. However, it is easier and faster to use slice replacement with an implicit or explicit forward iteration. Here are three variations:

mylist[:] = filter(keep_function, mylist)
mylist[:] = (x for x in mylist if keep_condition)
mylist[:] = [x for x in mylist if keep_condition]

リスト内包表記がおそらく最も高速です。

Python で配列を作るにはどうしますか?

リストを使ってください:

["this", 1, "is", "an", "array"]

リストの時間計算量は C や Pascal の配列と同じです。大きな違いは、Python のリストは多くの異なる型のオブジェクトを含めることです。

The array module also provides methods for creating arrays of fixed types with compact representations, but they are slower to index than lists. Also note that NumPy and other third-party packages define array-like structures with various characteristics as well.

Lisp 方式の連結リストを得るのに、タプルを使って cons cells をエミュレートできます:

lisp_list = ("like",  ("this",  ("example", None) ) )

ミュータブルな必要があるなら、タプルではなくリストを使いましょう。Lisp の car にあたるものが lisp_list[0] で、cdr にあたるものが lisp_list[1] です。本当に必要だと確信できるとき以外はこれはしないでください。たいてい、これは Python のリストを使うよりも非常に遅いですから。

多次元のリストを作るにはどうしますか?

このようにして多次元の配列を作ろうとしてしまったことがあるでしょう:

>>> A = [[None] * 2] * 3

これを表示したときには問題なさそうに見えます:

>>> A
[[None, None], [None, None], [None, None]]

しかし値を代入すると、その値が複数の場所に現れてしまいます:

>>> A[0][0] = 5
>>> A
[[5, None], [5, None], [5, None]]

これは、* を使ったリストの複製がコピーを作らず、存在するオブジェクトへの参照を作るだけだからです。この *3 は長さ 2 の同じリストへの参照を含むリストを作ります。一つの列に対する変更はすべての列に現れますが、これが望んだ結果であることはまずないでしょう。

おすすめの方法は、最初に望んだ長さのリストを作り、それから新しく作ったリストでそれぞれの要素を埋めていくことです:

A = [None] * 3
for i in range(3):
    A[i] = [None] * 2

これは長さ 2 の異なるリスト 3 つを含むリストを生成します。リスト内包表記も使えます:

w, h = 2, 3
A = [[None] * w for i in range(h)]

あるいは、行列データ型を提供している拡張を使用することもできます; NumPy が最もよく知られています。

オブジェクトのシーケンスにメソッドや関数を適用するにはどうしますか?

To call a method or function and accumulate the return values in a list, a list comprehension is an elegant solution:

result = [obj.method() for obj in mylist]

result = [function(obj) for obj in mylist]

戻り値を保存せずにメソッドや関数を実行するだけなら、ただの for ループで十分です:

for obj in mylist:
    obj.method()

for obj in mylist:
    function(obj)

なぜ加算はされるのに a_tuple[i] += ['item'] は例外を送出するのですか?

これは、累算代入演算子は 代入 演算子だ、という事実と、Python での可変オブジェクトと不変オブジェクトの違いが組み合わさって起きるのです。

この議論は一般的に、可変オブジェクトを指すタプルの要素に、累算代入演算子が適用されたときにも適用できますが、例として list+= を使います。

次のように書いたとします:

>>> a_tuple = (1, 2)
>>> a_tuple[0] += 1
Traceback (most recent call last):
   ...
TypeError: 'tuple' object does not support item assignment

例外が送出された理由は明らかです: 1 が (1) を指すオブジェクト a_tuple[0] に加えられ、結果のオブジェクト 2 が生成されますが、計算結果 2 をタプルの第 0 要素に代入しようとしたときに、エラーが発生します。なぜならば、タプルの要素が何を指すかは変えられないからです。

このような裏事情の元、累算代入文はだいたい次のようなことをしています:

>>> result = a_tuple[0] + 1
>>> a_tuple[0] = result
Traceback (most recent call last):
  ...
TypeError: 'tuple' object does not support item assignment

タプルは不変なので、例外を生み出しているのは操作の代入部分なのです。

次のように書いたとします:

>>> a_tuple = (['foo'], 'bar')
>>> a_tuple[0] += ['item']
Traceback (most recent call last):
  ...
TypeError: 'tuple' object does not support item assignment

この例外にはちょっと驚きますが、もっと驚くべきことは、エラーがあったとしても追記はきちんと動いている、という事実です:

>>> a_tuple[0]
['foo', 'item']

To see why this happens, you need to know that (a) if an object implements an __iadd__() magic method, it gets called when the += augmented assignment is executed, and its return value is what gets used in the assignment statement; and (b) for lists, __iadd__() is equivalent to calling extend() on the list and returning the list. That's why we say that for lists, += is a "shorthand" for list.extend():

>>> a_list = []
>>> a_list += [1]
>>> a_list
[1]

これは次と等価です:

>>> result = a_list.__iadd__([1])
>>> a_list = result

a_list が指していたオブジェクトは更新され、更新されたオブジェクトへのポインタは再度 a_list に代入されます。代入しているのは、a_list が更新前まで指していた同じオブジェクトへのポインタなので、代入は最終的には何もしていないのですが、代入処理自体は起きています。

従って、今のタプルの例では、次のと同じことが起きています:

>>> result = a_tuple[0].__iadd__(['item'])
>>> a_tuple[0] = result
Traceback (most recent call last):
  ...
TypeError: 'tuple' object does not support item assignment

__iadd__() は成功し、リストは拡張 (extend) されますが、resulta_tuple[0] が既に指しているオブジェクトと同じオブジェクトを指していたとしても、タプルは不変なので、その最後の代入はやはりエラーとなります。

複雑なソートがしたいのですが、Python でシュワルツ変換はできますか?

Perl コミュニティの Randal Schwartz の作とされるこのテクニックは、リストの要素を、それぞれの要素をその「ソート値」に対応付けるメトリックによってソートします。Python では、 list.sort() メソッドに key 引数を使ってください:

Isorted = L[:]
Isorted.sort(key=lambda s: int(s[10:15]))

リストを別のリストの値によってソートするにはどうしますか?

Merge them into an iterator of tuples, sort the resulting list, and then pick out the element you want.

>>> list1 = ["what", "I'm", "sorting", "by"]
>>> list2 = ["something", "else", "to", "sort"]
>>> pairs = zip(list1, list2)
>>> pairs = sorted(pairs)
>>> pairs
[("I'm", 'else'), ('by', 'sort'), ('sorting', 'to'), ('what', 'something')]
>>> result = [x[1] for x in pairs]
>>> result
['else', 'sort', 'to', 'something']

オブジェクト

クラスとは何ですか?

クラスは、class 文の実行で生成される特殊なオブジェクトです。クラスオブジェクトはインスタンスオブジェクトを生成するためのテンプレートとして使われ、あるデータ型に特有のデータ (attribute/属性) とコード (メソッド) の両方を内蔵しています。

新しいクラスを一つ以上の他のクラス (新しいクラスの基底クラスと呼ばれます) に基づいて作ることもできます。この新しいクラスは、基底クラスから属性とメソッドを継承します。これにより、オブジェクトモデルを継承で連続的に洗練できます。メールボックスへの基本的なアクセサを提供する一般的な Mailbox クラスを作って、それからいろいろな特定のメールボックスの形式を扱う MboxMailboxMaildirMailboxOutlookMailbox のようなサブクラスを作れるのです。

メソッドとは何ですか?

メソッドは、オブジェクト x が持つ関数で、通常 x.name(arguments...) として呼び出されるものです。メソッドはクラス定義の中で関数として定義されます:

class C:
    def meth(self, arg):
        return arg * 2 + self.attribute

self とは何ですか?

self はメソッドの第一引数に慣習的につけられる名前にすぎません。meth(self, a, b, c) として定義されたメソッドは、その定義がなされたクラスのインスタンス x に対して x.meth(a, b, c) として呼び出されます。呼び出されたメソッドは、meth(x, a, b, c) が呼ばれたものと考えます。

なぜメソッドの定義や呼び出しにおいて 'self' を明示しなければならないのですか? も参照してください。

あるオブジェクトが、与えられたクラスやそのサブクラスのインスタンスであるかを調べるにはどうしますか?

Use the built-in function isinstance(obj, cls). You can check if an object is an instance of any of a number of classes by providing a tuple instead of a single class, for example, isinstance(obj, (class1, class2, ...)), and can also check whether an object is one of Python's built-in types, for example, isinstance(obj, str) or isinstance(obj, (int, float, complex)).

Note that isinstance() also checks for virtual inheritance from an abstract base class. So, the test will return True for a registered class even if hasn't directly or indirectly inherited from it. To test for "true inheritance", scan the method resolution order (MRO) of the class:

from collections.abc import Mapping

class P:
     pass

class C(P):
    pass

Mapping.register(P)
>>> c = C()
>>> isinstance(c, C)        # direct
True
>>> isinstance(c, P)        # indirect
True
>>> isinstance(c, Mapping)  # virtual
True

# Actual inheritance chain
>>> type(c).__mro__
(<class 'C'>, <class 'P'>, <class 'object'>)

# Test for "true inheritance"
>>> Mapping in type(c).__mro__
False

なお、大部分のプログラムでは、 isinstance() をユーザー定義のクラスに何度も使うべきではありません。クラスを自分で開発するときに、適切なオブジェクト指向スタイルは、特定の振る舞いをカプセル化するクラスのメソッドを定義するものであって、オブジェクトのクラスを調べてそのクラスに応じて違うことをするものではありません。例えば、何かをする関数があったとして:

def search(obj):
    if isinstance(obj, Mailbox):
        ...  # code to search a mailbox
    elif isinstance(obj, Document):
        ...  # code to search a document
    elif ...

よりよいアプローチは、search() メソッドをすべてのクラスに定義して、それをただ呼び出すことです:

class Mailbox:
    def search(self):
        ...  # code to search a mailbox

class Document:
    def search(self):
        ...  # code to search a document

obj.search()

委譲とは何ですか?

Delegation is an object-oriented technique (also called a design pattern). Let's say you have an object x and want to change the behaviour of just one of its methods. You can create a new class that provides a new implementation of the method you're interested in changing and delegates all other methods to the corresponding method of x.

Python プログラマは簡単に委譲を実装できます。例えば、以下のクラスは、ファイルのように振る舞いながらすべての文字を大文字に変換するクラスを実装します:

class UpperOut:

    def __init__(self, outfile):
        self._outfile = outfile

    def write(self, s):
        self._outfile.write(s.upper())

    def __getattr__(self, name):
        return getattr(self._outfile, name)

ここで UpperOut クラスは write() メソッドを定義しなおして、引数の文字列を大文字に変換してから基礎となる self._outfile.write() メソッドを呼び出すようにします。その他すべてのメソッドは基礎となる self._outfile オブジェクトに移譲されます。この委譲は __getattr__() メソッドを通してなされます。属性の制御の詳細は 言語リファレンス を参照してください。

なお、一般的に委譲はトリッキーになりがちです。属性が設定される時には読み出される時と同様に、そのクラスに __setattr__() メソッドを定義する必要があり、それには細心の注意が必要です。 __setattr__() の基本的な実装はおおよそ以下のようになります:

class X:
    ...
    def __setattr__(self, name, value):
        self.__dict__[name] = value
    ...

Many __setattr__() implementations call object.__setattr__() to set an attribute on self without causing infinite recursion:

class X:
    def __setattr__(self, name, value):
        # Custom logic here...
        object.__setattr__(self, name, value)

Alternatively, it is possible to set attributes by inserting entries into self.__dict__ directly.

基底クラスで定義されたメソッドを、そのクラスを継承した派生クラスから呼び出すにはどうしますか?

組み込みの super() 関数を使ってください:

class Derived(Base):
    def meth(self):
        super().meth()  # calls Base.meth

この例では、 super() は呼ばれたインスタンス (self の値) を自動判断し、 type(self).__mro__method resolution order (MRO メソッド解決順) を検索し、そしてMRO内で Derived の次行を返します: Base

基底クラスの名前を変えやすいコードを書くにはどうしますか?

You could assign the base class to an alias and derive from the alias. Then all you have to change is the value assigned to the alias. Incidentally, this trick is also handy if you want to decide dynamically (such as depending on availability of resources) which base class to use. Example:

class Base:
    ...

BaseAlias = Base

class Derived(BaseAlias):
    ...

静的なクラスデータや静的なクラスメソッドを作るにはどうしますか?

(C++ や Java の意味で) 静的なデータも静的なメソッドも Python でサポートされています。

静的なデータを作るには、単純にクラス属性を定義してください。その属性に新しい値を代入するには、代入するクラス名を明示する必要があります:

class C:
    count = 0   # number of times C.__init__ called

    def __init__(self):
        C.count = C.count + 1

    def getcount(self):
        return C.count  # or return self.count

c そのものや c.__class__ から C にいたるパス探索経路上のクラスによってオーバーライドされない限り、c.countisinstance(c, C) であるすべての c に対する C.count を参照します。

注意: C のメソッド内では、self.count = 42 のような代入は self 自身の辞書に "count" という名前の新しくて関係ないインスタンスを作ります。クラスの静的なデータの再束縛には、メソッド内であるか否かにかかわらず、いつもクラスを指定しなければなりません:

C.count = 314

静的メソッドが使えます:

class C:
    @staticmethod
    def static(arg1, arg2, arg3):
        # No 'self' parameter!
        ...

しかし、静的メソッドの効果を得るもっと簡単な方法は、単にモジュールレベル関数を使うことです:

def getcount():
    return C.count

モジュールあたりに一つのクラスを定義するように (あるいはクラス組織を厳密に関連させるように) コードが構成されているなら、これで必要なカプセル化ができます。

Python でコンストラクタ(やメソッド)をオーバーロードするにはどうしたらいいですか?

この質問の答えはすべてのメソッドについて言えることですが、この質問はだいたい以下の構造の文脈から出てきます。

In C++ you'd write:

class C {
    C() { cout << "No arguments\n"; }
    C(int i) { cout << "Argument is " << i << "\n"; }
}

Python では、一つのコンストラクタでデフォルトの引数を使ってすべての場合に対応するように書かなければなりません。例えば:

class C:
    def __init__(self, i=None):
        if i is None:
            print("No arguments")
        else:
            print("Argument is", i)

これで完全に等価とは言えませんが、実用上は十分に近いです。

You could also try a variable-length argument list, for example:

def __init__(self, *args):
    ...

これと同じやり方がすべてのメソッド定義で使えます。

__spam を使おうとしたら _SomeClassName__spam からエラーがでました。

先頭にアンダースコアが二つ付いた変数名は、クラスのプライベートな変数を、 "マングル化" という単純かつ効率のいい方法で定義します。__spam のような形式 (先頭に二つ以上、末尾にもしあっても一つのアンダースコアがある) のすべての識別子は、classname が先頭のアンダースコアをすべて削除した現在のクラス名とすれば、_classname__spam のように文字上で置換えられます。

The identifier can be used unchanged within the class, but to access it outside the class, the mangled name must be used:

class A:
    def __one(self):
        return 1
    def two(self):
        return 2 * self.__one()

class B(A):
    def three(self):
        return 3 * self._A__one()

four = 4 * A()._A__one()

In particular, this does not guarantee privacy since an outside user can still deliberately access the private attribute; many Python programmers never bother to use private variable names at all.

参考

詳細と特例は、 private name mangling specifications

クラスに __del__ メソッドを定義しているのですが、オブジェクトを削除したときに呼ばれません。

いくつかの可能性があります。

del 文は必ずしも __del__() を呼び出すとは限りません -- これは単純にオブジェクトの参照カウントを減らすもので、カウントがゼロになったときに __del__() が呼び出されます。

If your data structures contain circular links (for example, a tree where each child has a parent reference and each parent has a list of children) the reference counts will never go back to zero. Once in a while Python runs an algorithm to detect such cycles, but the garbage collector might run some time after the last reference to your data structure vanishes, so your __del__() method may be called at an inconvenient and random time. This is inconvenient if you're trying to reproduce a problem. Worse, the order in which object's __del__() methods are executed is arbitrary. You can run gc.collect() to force a collection, but there are pathological cases where objects will never be collected.

循環参照コレクタがあるとはいえ、オブジェクトに close() メソッドを明示的に定義し、使い終わったらいつでも呼び出せるようにするのはいいことです。 close() メソッドを使うと、サブオブジェクトを参照している属性を取り除けます。 __del__() を直接呼び出さないでください -- __del__()close() を呼び出すでしょうし、 close() なら同じオブジェクトに対して複数回呼ばれてもいいことが保証されているでしょう。

循環参照を避ける他の方法は、 weakref モジュールを使って、参照カウントを増やすことなくオブジェクトを示すことです。例えばツリー構造は、親と (必要なら!) 兄弟に弱参照を使うべきです。

最後に、 __del__() メソッドが例外を発生させた場合、警告のメッセージが sys.stderr に書きこまれます。

与えられたクラスのすべてのインスタンスのリストを得るにはどうしますか?

Python はクラス (やビルトイン型) のすべてのインスタンスをたどりません。クラスのコンストラクタにそれぞれのインスタンスへの弱参照のリストを作らせることですべてのインスタンスをたどらせられます。

なぜ id() の結果は一意でないように見えるのですか?

組み込みの id() は、オブジェクトが生存している間は一意なことが保証されている整数値を返します。 CPython では、それはオブジェクトのメモリアドレスなので、オブジェクトがメモリから削除された後に、次に新しく生成されたオブジェクトはメモリの同じ場所にメモリ領域を確保されていることが、しばしば起きます。この現象を次の例で示しましょう:

>>> id(1000)
13901272
>>> id(2000)
13901272

2 つの同じ値を持つ id は id() の実行の前に作られてすぐさま削除された異なる整数オブジェクトによるものです。id を調べたいオブジェクトがまだ生きてることを保証したいなら、オブジェクトへの別の参照を作ってください:

>>> a = 1000; b = 2000
>>> id(a)
13901272
>>> id(b)
13891296

いつ is 演算子での同一性テストが頼れますか?

is 演算子はオブジェクトの同一性をテストします。 テスト a is bid(a) == id(b) と同等です。

同一性テストの最も重要な特性は、オブジェクトは常にそれ自身と同一であり、 a is a は常に True を返すということです。 同一性テストは通常、等価性テストよりも高速です。 また、等価性テストとは異なり、同一性テストは真偽値 True または``False`` を返すことが保証されています。

ただし、同一性テストを等価性テストの代用とできるのは、オブジェクトの同一性が保証されている場合 のみ です。 一般的に、同一性が保証される状況は3つあります:

  1. Assignments create new names but do not change object identity. After the assignment new = old, it is guaranteed that new is old.

  2. Putting an object in a container that stores object references does not change object identity. After the list assignment s[0] = x, it is guaranteed that s[0] is x.

  3. If an object is a singleton, it means that only one instance of that object can exist. After the assignments a = None and b = None, it is guaranteed that a is b because None is a singleton.

多くの他の状況では、同一性テストは賢明でなく、等価性テストをお勧めします。 特に、シングルトンであることが保証されていない intstr などの定数をチェックするために同一性テストを使わないでください。

>>> a = 10_000_000
>>> b = 5_000_000
>>> c = b + 5_000_000
>>> a is c
False

>>> a = 'Python'
>>> b = 'Py'
>>> c = b + 'thon'
>>> a is c
False

同様に、ミュータブルなコンテナの新しいインスタンスは同一ではありません:

>>> a = []
>>> b = []
>>> a is b
False

標準ライブラリのコードには、同一性テストを正しく使うための一般的なパターンがあります:

  1. PEP 8 で推奨されているとおり、同一性テストは None をチェックする際に望ましい方法です。これはコードの中で自然な英語に読むことができ、また

  2. オプション引数の検出は、 None が有効な入力値である場合に厄介なことになる場合があります。この状況では、他のオブジェクトと必ず区別できる唯一のマーカーオブジェクト( singleton sentinel object )を作ることで対策できます。例えば、 dict.pop() のように振る舞うメソッドを実装する方法を示します:

    _sentinel = object()
    
    def pop(self, key, default=_sentinel):
        if key in self:
            value = self[key]
            del self[key]
            return value
        if default is _sentinel:
            raise KeyError(key)
        return default
    
  3. コンテナの実装では、等価性テストを同一性テストで補強する必要がある場合があります。これは、 float('NaN') のような自分自身と等しくないオブジェクトによってコードが混乱するのを防ぎます。

例えば、これは collections.abc.Sequence.__contains__(): の実装です:

def __contains__(self, value):
    for v in self:
        if v is value or v == value:
            return True
    return False

どうすればサブクラスはイミュータブルなインスタンスに格納されたデータを制御できますか?

イミュータブル型をサブクラス化する場合、 __init__() ではなく __new__() メソッドを継承します。 前者はインスタンスが生成された に動くため、イミュータブルなインスタンスのデータを変えるには遅すぎます。

これらのイミュータブルクラスはすべて、親クラスと異なるシグネチャを持ちます:

import datetime as dt

class FirstOfMonthDate(dt.date):
    "Always choose the first day of the month"
    def __new__(cls, year, month, day):
        return super().__new__(cls, year, month, 1)

class NamedInt(int):
    "Allow text names for some numbers"
    xlat = {'zero': 0, 'one': 1, 'ten': 10}
    def __new__(cls, value):
        value = cls.xlat.get(value, value)
        return super().__new__(cls, value)

class TitleStr(str):
    "Convert str to name suitable for a URL path"
    def __new__(cls, s):
        s = s.lower().replace(' ', '-')
        s = ''.join([c for c in s if c.isalnum() or c == '-'])
        return super().__new__(cls, s)

クラスはこのように使えます:

>>> FirstOfMonthDate(2012, 2, 14)
FirstOfMonthDate(2012, 2, 1)
>>> NamedInt('ten')
10
>>> NamedInt(20)
20
>>> TitleStr('Blog: Why Python Rocks')
'blog-why-python-rocks'

メソッド呼び出しをキャッシュするには どうしたらいいですか?

メソッドキャッシュの主な道具は2つあり、 functools.cached_property()functools.lru_cache() です。前者はインスタンスレベル、後者はクラスレベルで結果を保存します。

The cached_property approach only works with methods that do not take any arguments. It does not create a reference to the instance. The cached method result will be kept only as long as the instance is alive.

利点は、インスタンスが使われなくなった場合、キャッシュされたメソッドの結果がすぐに解放されることです。欠点は、インスタンスが溜まると、溜められたメソッドの結果も増えてしまうことです。それらは際限なく増える恐れがあります。

The lru_cache approach works with methods that have hashable arguments. It creates a reference to the instance unless special efforts are made to pass in weak references.

least recently used アルゴリズム(訳注:LRU 直近に使われたものを残す)の利点は、キャッシュが指定された maxsize で制限されることです。欠点は、キャッシュから期限切れで追い出されるかクリアされるまで、インスタンスが生き続けることです。

この例は各種テクニックを示します:

class Weather:
    "Lookup weather information on a government website"

    def __init__(self, station_id):
        self._station_id = station_id
        # The _station_id is private and immutable

    def current_temperature(self):
        "Latest hourly observation"
        # Do not cache this because old results
        # can be out of date.

    @cached_property
    def location(self):
        "Return the longitude/latitude coordinates of the station"
        # Result only depends on the station_id

    @lru_cache(maxsize=20)
    def historic_rainfall(self, date, units='mm'):
        "Rainfall on a given date"
        # Depends on the station_id, date, and units.

The above example assumes that the station_id never changes. If the relevant instance attributes are mutable, the cached_property approach can't be made to work because it cannot detect changes to the attributes.

To make the lru_cache approach work when the station_id is mutable, the class needs to define the __eq__() and __hash__() methods so that the cache can detect relevant attribute updates:

class Weather:
    "Example with a mutable station identifier"

    def __init__(self, station_id):
        self.station_id = station_id

    def change_station(self, station_id):
        self.station_id = station_id

    def __eq__(self, other):
        return self.station_id == other.station_id

    def __hash__(self):
        return hash(self.station_id)

    @lru_cache(maxsize=20)
    def historic_rainfall(self, date, units='cm'):
        'Rainfall on a given date'
        # Depends on the station_id, date, and units.

モジュール

.pyc ファイルを作るにはどうしますか?

モジュールが初めてインポートされたとき (もしくは、現在のコンパイルされたファイルが作られてから、ソースファイルが変更されたとき) 、コンパイルされたコードが入っている .pyc ファイルが、 .py ファイルのあるディレクトリのサブディレクトリ __pycache__ に作成されます。 .pyc ファイルのファイル名は、 .py ファイルの名前で始まり、 .pyc で終わり、中間部分はこのファイルを作った python バイナリに依存した文字列になります。 (詳細は PEP 3147 を参照してください。)

.pyc が作られない理由の 1 つは、ソースファイルがあるディレクトリの権限の問題、つまり __pycache__ サブディレクトリが作れない問題です。これは、例えば、ウェブサーバーでテストを行っているときのような、開発者のユーザと実行者のユーザが別な場合に、起こり得ます。

Unless the PYTHONDONTWRITEBYTECODE environment variable is set, creation of a .pyc file is automatic if you're importing a module and Python has the ability (permissions, free space, and so on) to create a __pycache__ subdirectory and write the compiled module to that subdirectory.

Running Python on a top-level script is not considered an import and no .pyc will be created. For example, if you have a top-level module foo.py that imports another module xyz.py, when you run foo (by typing python foo.py as a shell command), a .pyc will be created for xyz because xyz is imported, but no .pyc file will be created for foo since foo.py isn't being imported.

foo.pyc ファイルを作成する -- つまり、インポートされていないモジュールの .pyc ファイルを作成する -- 必要がある場合、 py_compile モジュールと compileall モジュールを使えば可能です。

py_compile モジュールは手動で任意のモジュールをコンパイルできます。やり方の一つは、このモジュールの compile() 関数をインタラクティブに実行することです:

>>> import py_compile
>>> py_compile.compile('foo.py')

This will write the .pyc to a __pycache__ subdirectory in the same location as foo.py (or you can override that with the optional parameter cfile).

compileall モジュールを使えば自動的に一つや複数のディレクトリのすべてのファイルをコンパイルできます。シェルプロンプトから compileall.py を起動して、コンパイルしたいファイルを含むディレクトリのパスを指定してください:

python -m compileall .

現在のモジュール名を知るにはどうしますか?

モジュールは前もって定義されたグローバル変数 __name__ を検索することで自身の名前を決定できます。この値が '__main__' であるとき、そのプログラムはスクリプトとして実行されています。インポートされることによって使われる大抵のモジュールはコマンドラインインターフェースや自己テストも提供していて、__name__ をチェックしてからそのコードだけを実行します:

def main():
    print('Running test...')
    ...

if __name__ == '__main__':
    main()

相互にインポートしあうモジュールを作るにはどうしたらいいですか?

以下のモジュールがあったとしましょう:

foo.py:

from bar import bar_var
foo_var = 1

bar.py:

from foo import foo_var
bar_var = 2

問題はインタプリタが以下の段階を実行することです:

  • main が foo をインポートする

  • foo の空のグローバルが生成される

  • foo がコンパイルされ実行を始める

  • foobar をインポートする

  • bar の空のグローバルが生成される

  • bar がコンパイルされ実行を始める

  • barfoo をインポートする(すでに foo という名前のモジュールがあるので no-op となる)

  • インポートメカニズムは foo のグローバルから foo_var を読んで、 bar.foo_var = foo.foo_var に設定しようとします。

この最後の段階は失敗します。Python が foo を解釈し終わっていなくて、foo のグローバルなシンボルの辞書はまだ空ですから。

import foo を使って、グローバルコードの foo.foo_var にアクセスしようとしたときにも、これと同じことが起こります。

この問題には (少なくとも) 三つの解決策があります。

Guido van Rossum は from <module> import ... を全く使わないで、すべてのコードを関数の中に入れることを勧めています。グローバル変数とクラス変数の初期化は定数とビルトイン関数のみで行われるべきです。これでインポートされたすべてのモジュールは <module>.<name> として参照されることになります。

Jim Roskind はそれぞれのモジュールに対して以下の順に進めることを提案しています:

  • エクスポート (インポートされた基底クラスを必要としないグローバル、関数、クラス)

  • import

  • アクティブなコード (インポートされた値によって初期化されるグローバルを含む)。

インポートが奇妙な場所に現れることから Van Rossum はこの方法をそれほど好みませんが、これは有効です。

Matthias Urlichs は第一に再帰インポートが必要ないようにコードを構築しなおすことを推奨しています。

これらの解決策はそれぞれ両立させることもできます。

__import__('x.y.z') は <module 'x'> を返しますが、z を得るためにはどうしますか?

importlibimport_module() という便利な関数があるので、代わりにそちらを使用することを検討してください。

z = importlib.import_module('x.y.z')

インポートされたモジュールを編集してから再インポートしましたが、変化が現れません。なぜですか?

効率と一貫性上の理由から、Python はモジュールが最初にインポートされた時にのみモジュールファイルを読み込みます。そうしないと、たくさんのモジュールでできていて、それぞれが同じ基本モジュールをインポートしているようなプログラムでは、その基本モジュールの解析と再解析が繰り返されることになります。変更されさたモジュールの再読込を強制するには、こうしてください:

import importlib
import modname
importlib.reload(modname)

Warning: this technique is not 100% fool-proof. In particular, modules containing statements like:

from modname import some_objects

のような文を含むモジュールは、インポートされたオブジェクトの古いバージョンを使い続けます。そのモジュールにクラス定義が含まれていたら、存在するクラスインスタンスは新しいクラス定義を使うようにアップデート されません。これによって以下の矛盾した振舞いがなされえます:

>>> import importlib
>>> import cls
>>> c = cls.C()                # Create an instance of C
>>> importlib.reload(cls)
<module 'cls' from 'cls.py'>
>>> isinstance(c, cls.C)       # isinstance is false?!?
False

この問題の本質は、クラスオブジェクトの "固有値" を印字することで明らかになります:

>>> hex(id(c.__class__))
'0x7352a0'
>>> hex(id(cls.C))
'0x4198d0'