質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

3回答

10944閲覧

Python の オブジェクトID と メモリアドレス の関係について教えてください。

7968

総合スコア253

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

2クリップ

投稿2018/08/28 07:06

Python 初学者です。

PHP の基礎を学びましたが、他の言語知識は、ほぼありません。

PHP を学んだときに内部で refcountis_ref などで変数名と値を管理しているということを学び、理解が深まりました。

Pythonの入門書を読んだ程度ですが、理解を深めるために Python の内部でどのように処理されているか調べています。

調べていて、Python の オブジェクトID と メモリアドレス の関係について理解できていないので、教えてください。

id() でオブジェクトの「識別値(identity)」を知ることができます。

この識別値がオブジェクトIDかと思います。

Pythonのドキュメントを見ると下記のように記載されています。

CPython 実装の詳細: CPython では、id(x) は x が格納されているメモリ上のアドレスを返します。

3. データモデル — Python 3.6.5 ドキュメント

CPythonはC言語で記述された処理系ということは存じています。

気になるのは「メモリ上のアドレス」ということです。

私の中ではメモリ上のアドレスというと 0x7fffc0c5d57c のように16進数で表示されるという認識です。

ですが、Python の id() では整数で表示されます。

勝手な憶測ですが、メモリ上のアドレスを10進数で表しているわけではないと思います。

質問1

これは id() 関数がメモリ上のアドレスをもとにして、整数で表したということでしょうか?
それとも、メモリ上のアドレスとは関係なしにオブジェクトごとにオブジェクトIDが付けられているのでしょうか?

質問2

オブジェクトIDがオブジェクトごとに割り振られているから不明ですが、このオブジェクトID(identity?)が内部で表すとどこに該当するかわかりませんでした。(C言語に関する理解が浅いため;;)

下記は調べたときの内部構造を表した図です。

イメージ説明

引用元:Python 源码阅读 - 类型

イメージ説明

引用元:python原始碼 - 型別 - 程序員的後花園

オブジェクトIDがオブジェクトごとに割り振られているとした場合、内部構造で表すとどこに位置するのでしょうか?

質問の意図がわかりにくいところもあるかもしれませんが、ご存知の方いれば、教えてくださいm(__)m

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tachikoma

2018/08/28 07:18

メモリのアドレスは2進数、10進数、16進数どれで表現してもいいものなのですが。
7968

2018/08/28 07:21

はい、それは存じてます。id()で表示されるオブジェクトID(整数)はメモリアドレスを10進数で表したものということですか?
tachikoma

2018/08/28 07:23

はい、その理解でいいと思います。
tachikoma

2018/08/28 07:25

ただ私自身はCPythonの実装を見たことはないですm(_ _;)m
guest

回答3

0

ベストアンサー

https://github.com/python/cpython/blob/627d0c61ac96009450e3794a2401f244e56fcb79/Python/bltinmodule.c#L1091

PyObjectへのポインタを

https://github.com/python/cpython/blob/627d0c61ac96009450e3794a2401f244e56fcb79/Objects/longobject.c#L990

unsigned longにキャストして

https://github.com/python/cpython/blob/627d0c61ac96009450e3794a2401f244e56fcb79/Objects/longobject.c#L301

その整数を表現する(Python言語の)整数オブジェクト」を作って返してますね。

答え: C言語のPyObjectへのポインタをunsigned longにキャストした整数値

投稿2018/08/28 08:10

編集2018/08/28 08:12
quickquip

総合スコア11038

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

7968

2018/08/28 08:15

詳細な解説ありがとうございます。 PyObjectへのポインタなのですね。 勉強になります、ありがとうございますm(__)m
退会済みユーザー

退会済みユーザー

2018/08/28 10:16

quiquiさん builtin_idが対応する関数だっていうのはどうやって特定したのですか? デバッガですか?CPythonの構造を知っていたのですか? 私もCPythonのソースコードを見ていたのですがまだ見つけられていませんでした。 今後のためにご教示いただけると幸いです。
quickquip

2018/08/28 11:11 編集

Web検索したら解説記事がでてきただけです。それはこの件とは話のポイントが違ったので引用しませんでしたが。わかったのはファイル名と関数名でしたがそれで十分ですね。
退会済みユーザー

退会済みユーザー

2018/08/28 14:13

なんだ検索しただけか。 なんだ。
退会済みユーザー

退会済みユーザー

2018/08/28 14:14

検索して出てこなかったらデバッガかなあ
quickquip

2018/08/28 15:02 編集

PythonディレクトリとModulesディレクトリにざっと目を通しちゃった方が早い気がします。レキサやパーザや(Pythonバイトコードの)実行部分に興味があるのでなければですが。
guest

0

16進数を理解できてないだけのような?

python

1hoge = id("hoge") 2print("{} 0x{:x}".format(hoge, hoge)) 3# 139772608496448 0x7f1f58adc340

1397726084964480x7f1f58adc340は同じ値ですよ。

投稿2018/08/28 08:04

fuzzball

総合スコア16731

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

7968

2018/08/28 08:16

なるほど、format で16進数に変換して確認することもできるのですね。 勉強になりますm(__)m
退会済みユーザー

退会済みユーザー

2018/08/28 10:07

確認目的ならhex(id("hoge"))でいけますよ hoge = id("hoge") print("{} {}".format(hoge, hex(hoge))) の方がキモくなくて良いかな
guest

0

IDが何を表すか、というのは処理系依存なはなしなわけで、これはメモリアドレスを指すという処理系があるかもしれない、という程度のものと思っておきましょう。

質問1
もしかすれば、オブジェクトを保持しているテーブルのインデックス番号かもしれない。こんな場合はアドレスとは全く関係ない数字となりますね

質問2
それは実装者しかわからんでしょうね。その処理図にしても、そのとおりにPythonが実装されているとは限らない、ということを注意しておきましょう

投稿2018/08/28 07:38

y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

7968

2018/08/28 08:19

確かにCPython以外にいくつか処理系があるようなので、一例と考えておいた方がいいですね。 ありがとうございますm(__)m
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問