問題タブ [python-internals]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
4 に答える
13919 参照

python - Python Bytecode Run in CPython とはどのくらい正確ですか?

Python がどのように機能するかを理解しようとしています (常に使用しているためです!)。私の理解では、python script.py のようなものを実行すると、スクリプトがバイトコードに変換され、インタプリタ/VM/CPython (実際には単なる C プログラム) が python バイトコードを読み取り、それに応じてプログラムを実行します。

このバイトコードはどのように読み込まれますか? C でテキスト ファイルを読み取る方法に似ていますか。Python コードがどのように機械語コードに変換されるのかわかりません。Python インタープリター (CLI の python コマンド) は、実際には既にマシン コードに変換されたプリコンパイル済みの C プログラムであり、Python バイトコード ファイルはそのプログラムを通過するだけなのでしょうか? 言い換えれば、私の Python プログラムは実際には機械語に変換されないのでしょうか? Python インタープリターは既にマシン コードに組み込まれているので、スクリプトを記述する必要はありませんか?

0 投票する
5 に答える
4260 参照

python - リスト内包表記フィルタリング - 「set() トラップ」

合理的に一般的な操作はlist、別のものに基づいて1 つをフィ​​ルタリングすることlistです。人々はすぐに次のことに気付きます。

大きな入力に対しては遅いです - それは O(n*m) です。うん。どうすればこれをスピードアップできますか? a を使用しsetて、フィルタリング ルックアップ O(1) を作成します。

これにより、全体的に O(n) の動作が適切になります。しかし、ベテランのコーダーでさえ、 The Trap ™に陥るのをよく見かけます。

あっ!Python は 1回だけでなくset(list_2) 毎回ビルドするため、これも O(n*m)です。


私はそれが話の終わりだと思った-pythonはそれを最適化してset一度だけ構築することはできない。落とし穴に注意してください。それと一緒に暮らす必要があります。うーん。

ええ、python (3.3)は集合リテラルを最適化できます。f()おそらく aLOAD_GLOBALを aに置き換えるため、この場合よりもさらに高速ですLOAD_FAST

Python 2 は特にこの最適化を行いません。私はpython3が何をしているのかをさらに調査しようとしましたが、残念ながらdis.dis理解表現の内部を調べることはできません. 基本的に興味深いものはすべて に変わりますMAKE_FUNCTION

だから今私は疑問に思っています-なぜpython 3.xはセットリテラルを最適化して1回だけビルドすることができset(list_2)ますか?

0 投票する
4 に答える
140 参照

python - CPython Dicts が負の 1 と負の 2 のハッシュ値の影響を受けないのはなぜですか?

ハッシュ テーブルは高パフォーマンスのマッピングであると想定されており、Python dict はハッシュ テーブルで実装されているため、高パフォーマンスでもあります。しかし、負の整数のハッシュ値を見ると、奇妙な結果に遭遇しました。

しかし、これは明らかに辞書には影響しません:

なぜこれが起こるのですか? また、辞書を使用しても影響を受けないのはなぜですか?

0 投票する
3 に答える
6711 参照

python - Python での変数への参照の解決方法

このメッセージは多くの例で少し長くなりますが、Python 2.7 での変数と属性ルックアップの完全なストーリーをよりよく理解するのに役立つことを願っています。

コードブロック(モジュール、クラス定義、関数定義など)と変数バインディング(代入、引数の宣言、クラスと関数の宣言、for ループなど)

ドットなしで呼び出すことができる名前には変数という用語を使用し、オブジェクト名で修飾する必要がある名前には属性という用語を使用しています (オブジェクト obj の属性 x の obj.x など)。

Python には、すべてのコード ブロックに対して 3 つのスコープがありますが、関数は次のとおりです。

  • ローカル
  • グローバル
  • ビルトイン

関数専用の Python には 4 つのブロックがあります (PEP 227 によると)。

  • ローカル
  • 囲み関数
  • グローバル
  • ビルトイン

変数をバインドしてブロック内で見つけるためのルールは非常に単純です。

  • ブロック内のオブジェクトに変数をバインドすると、変数がグローバルに宣言されていない限り (その場合、変数はグローバル スコープに属します)、この変数はこのブロックに対してローカルになります。
  • 変数への参照は、すべてのブロックに対してルール LGB (ローカル、グローバル、ビルトイン) を使用して検索されますが、関数は
  • 変数への参照は、関数に対してのみルール LEGB (ローカル、エンクロージング、グローバル、ビルトイン) を使用して検索されます。

このルールを検証し、多くの特殊なケースを示す例を教えてください。それぞれの例について、私の理解を示します。間違っている場合は修正してください。最後の例については、結果がわかりません。

例 1:

クラスのネストされたスコープはなく (ルール LGB)、クラス内の関数は、修飾名 (この例では self.x) を使用しないとクラスの属性にアクセスできません。これは PEP227 で詳しく説明されています。

例 2:

ここで、関数内の変数は LEGB ルールを使用して検索されますが、クラスがパスにある場合、クラスの引数はスキップされます。繰り返しますが、これは PEP 227 が説明していることです。

例 3:

Python などの動的言語では、すべてが動的に解決されることが期待されます。しかし、これは関数には当てはまりません。ローカル変数はコンパイル時に決定されます。PEP 227 および http://docs.python.org/2.7/reference/executionmodel.htmlは、この動作をこのように説明しています

「名前バインディング操作がコード ブロック内のどこかで発生した場合、ブロック内の名前のすべての使用は、現在のブロックへの参照として扱われます。」

例 4:

しかし、PEP227 のこのステートメントは、「コード ブロック内の任意の場所で名前バインディング操作が発生した場合、ブロック内の名前のすべての使用は、現在のブロックへの参照として扱われます。」コードブロックがクラスの場合は間違っています。また、クラスについては、コンパイル時ではなく、実行時にクラスの名前空間を使用してローカルの名前バインディングを行うようです。その点で、PEP227 と Python doc の実行モデルは誤解を招きやすく、一部が間違っています。

例 5:

このコードの私の理解は次のとおりです。命令 x = x は、最初に式の右手 x が参照しているオブジェクトを調べます。その場合、オブジェクトはクラス内でローカルに検索され、次にルール LGB に従って、文字列 'x in module' であるグローバル スコープで検索されます。次に、MyClass へのローカル属性 x がクラス ディクショナリに作成され、文字列オブジェクトを指します。

例 6:

ここで、説明できない例を示します。これは例 5 に非常によく似ています。ローカルの MyClass 属性を x から y に変更しているだけです。

その場合、MyClass の x 参照が最も内側の関数で検索されるのはなぜですか?

0 投票する
3 に答える
3893 参照

python - Python の 'len' 関数が __len__ メソッドよりも速いのはなぜですか?

Python では、オブジェクトのメソッドlenを呼び出してコレクションの長さを取得する関数です。__len__

__len__()したがって、 の直接呼び出しは、少なくとも と同じくらい高速であると予想されlen()ます。

デモリンク

しかし、上記のコードでテストした結果は、より高速であることが示さlen()れています。なんで?

0 投票する
4 に答える
326 参照

python - `a` のスライス (例: `a[1:] == a[:-1]`) は `a` のコピーを作成しますか?

私の友人が次の Python コードを見せてくれました。

aすべての項目が同一である場合に True を返します。

私は、このコードは一目で理解するのが難しく、さらにa、比較のために のコピーが 2 つ作成されるため、メモリの使用効率が悪いと主張しました。

Python を使用disして、ボンネットの背後で何が起こっているかを確認しましたa[1:]==a[:-1]

それは 2 つのスライス コマンドに要約されます -SLICE+1SLICE+2. ドキュメントは、これらのオペコードが実際に の新しいコピーを作成するのかa、それとも単なる参照を作成するのかについて明確ではありません。

  • SLICE コマンドはコピーしますaか?
  • 答えは Python の実装 (Cython、Jython) によって異なりますか?

アップデート

このスニペットは明らかに判読不能で紛らわしいので、実際のコードで使用するつもりはありません。私の関心は純粋に技術的なものです - スライスがリストをコピーするかどうか、そして答えが状況によって異なるかどうかです。

0 投票する
3 に答える
16479 参照

python - Python スワッピング リスト

Python では、リストを別のリストに割り当てると、次のようになります。

これで b と a は同じリストを指します。ここで、2 つのリストを考えます。

では、それらが他のデータ型と同じように交換され、両方が同じリストを指していないのはなぜでしょうか?

0 投票する
1 に答える
132 参照

python - ジェネレーターを書くか、ジェネレーターを返しますか?

コンテナー クラス内で、そのアイテム (またはそのアイテムの変換、またはそのアイテムのサブセット) を反復処理する場合は、ジェネレーター ( など)を作成するか、ジェネレーター ( など)f返すgことができます。

を介してジェネレーターに情報を渡す必要はありませんsend

どうやら、どちらの方法も(表面では)同じように動作します。

  1. どのアプローチが望ましいですか?またその理由は?

  2. オーバーヘッドが少ないアプローチ、または私が見つけられない他の利点があるアプローチはどれですか?

0 投票する
4 に答える
4320 参照

python - 同じ Python モジュールの 2 つのインスタンス?

「a!」を出力するだけの単一の関数を持つ Python モジュールを作成しました。Python インタープリターを開き、モジュールを 2 つの異なる構文でインポートしました

この時点で、 func を変更して別のものを出力し、再度評価します

モジュールがリロードされていないため、これは当然のことです。次に、モジュールをリロードし、両方の機能が更新されることを期待しましたが、次のようになりました。

a.func だけが更新されるようです。Python は同じモジュールのインスタンスを 1 つだけ保持しているといつも思っていましたが、現在は 2 つあるようです。私の主張を検証するためにさらにテストを行い、モジュールの最上位に print ステートメントを追加し、インタープリターを再起動して再度インポートしました。

「モジュールがインポートされました」が2回表示されると思っていたので、これはさらに混乱します。私が行った 3 番目の実験は、グローバル変数の実験でした。

モジュールのインスタンスは 1 つですが、内部のオブジェクトのインスタンスは異なるのでしょうか? このような動作でGevent のモンキー パッチを実装するにはどうすればよいでしょうか?