'id'はPythonの不正な変数名です


141

idPythonで変数に名前を付けるのはなぜ悪いのですか?


33
ほとんどの人は組み込み/キーワードと衝突する識別子に下線を追加します:id_、map_、list_、filter_など
cdleary

3
より卑劣な解決策は、変数を使用することですID
Simon Kuang、2015

45
よりよい質問は...組み込み関数にこのような一般的で一般的な名前を使用することはどのような天才だと思いましたか?
基本的な

回答:


143

id() 基本的な組み込みです:

idモジュールの 組み込み関数のヘルプ__builtin__

id(...)

    id(object) -> integer

    Return the identity of an object.  This is guaranteed to be unique among
    simultaneously existing objects.  (Hint: it's the object's memory
    address.)

一般に、キーワードや組み込み関数を任意の言語で使用する変数名を使用することは、たとえ許可されていても、お勧めできません。


3
OK、「id」は正しいですが、「一般的に...」というコメントが引き続き適用されますね。
Kevin Little

5
確かに、モジュールグローバルについては回避します。ローカルスコープに制限された変数の場合、同じ関数が組み込み関数を使用する必要がないことがわかるので、心配する必要はありません。
ボビンス2009

@Caramdir:一度idに除去される予定でしたが、最終的には除去しないことにしました。元のコメントは編集できなくなったので、今後混乱を避けるために削除します。
Eli Courtwright、2014年

20
@EliCourtwright彼らがそれを削除したかったのに。なんと悪い名前のメソッドでしょう!何千もの場所で使用される一般的で一般的な名前(コンテキストが意味を与える場合)。それで、誰かがコンテキストのないグローバル名としてそれを使用することに決めましたか?
基本的な

2
驚くべきことに、Google独自のPython正規表現チュートリアル(developers.google.com/edu/python/regular-expressions)ではを使用していstr = 'an example word:cat!!'ます。これを実行しないと言っているPEPの中に何かありますか?
wordsforthewise

57

ではPEP 8 - Pythonのコードのためのスタイルガイド、セクションに次のガイダンスが表示されます記述:ネーミングスタイル

  • single_trailing_underscore_ :慣例により、Pythonキーワードとの競合を回避するために使用されます。

    Tkinter.Toplevel(master, class_='ClassName')

したがって、質問に答えるために、このガイドラインを適用する例は次のとおりです。

id_ = 42

変数名に末尾のアンダースコアを含めると、意図が明確になります(PEP 8のガイダンスに詳しい人には)。


1
これは、実際の質問に答えるが、PEP-8の命名規則のための+1されません
EGE

良いアドバイスidですが、組み込みではなくキーワードです。これは、組み込みをシャドウするのが悪い理由を説明していません。
wjandrea

51

idは、オブジェクト(CPythonではそのメモリアドレスでもあります)のIDを提供する組み込み関数です。関数の1つに名前を付ける場合は、元の関数(またはCPython)を取得idするように言う必要があります。グローバルに名前を変更すると、小さなスクリプト以外では混乱を招きます。builtins.id__builtins__.idid

ただし、組み込みの名前を変数として再利用することは、使用がローカルである限り、それほど悪いことではありません。Pythonは持っている多くの(1)あなたは多くとにかく使用することはありません一般的な名前と(2)を持っていることを組み込み関数のを。これらをローカル変数として、またはオブジェクトのメンバーとして使用することは、コンテキストから明らかであるため、問題ありません。

例:

def numbered(filename):
    with open(filename) as file:
        for i, input in enumerate(file):
            print("%s:\t%s" % (i, input), end='')

魅力的な名前を持ついくつかの組み込み:

  • id
  • file
  • listdict
  • map
  • allany
  • complexint
  • dir
  • input
  • slice
  • buffer
  • sum
  • minmax
  • object

8
2013年8月1日に更新されたPEP 8では_、変数名に追加するだけで混乱の可能性を回避するようにアドバイスされています。私の答えをください。
DavidRR、2015年

1
idオブジェクトのメモリアドレスを返す関数がCPython実装の詳細であることは注目に値します。また、この関数は、任意の2つの現存するオブジェクトに対して異なる数を返すためにのみ必要であることにも注意する必要があります。オブジェクトがガベージコレクションされている場合、そのIDはリサイクルされます。
Zac Crites 2016年

@ザックありがとう!回答を編集して、メモリアドレスに関するそのポイントと、人々がもっと読むことができるようにリンクを追加しました。
wjandrea

42

ここで不評なことを言うかもしれませんid()。ビジネスロジックではほとんど使用されない、かなり特殊な組み込み関数です。したがって、タイトで適切に記述された関数で変数名として使用することに問題はありません。idが組み込み関数を意味しないことは明らかです。


1
への対応:> idは、ビジネスロジックでめったに使用されない、かなり特殊な組み込み関数です。したがって、私はそれを変数として使用する際の問題を確認していません>タイトでよく記述された関数で>名前がid>が組み込み関数を意味していないことは明らかですが これは事実ですが、単に「id」ではなく、この変数名をより具体的にすることをお勧めします。多くのものがIDを持ち(特にRDBMSで作業している場合)、Tim Petersの2行目の「Pythonの禅」で次のように説明されています。>明示的は暗黙的よりも優れています。:実行して残りの部分を参照してくださいimport this
ロス

9
とはいえ、できればそれでも避けたいと思います。同僚が不平を言うのを聞く以外に理由がないとしても。:-)
Jason Baker

1
私は完全に同意します。小さな関数(つまりスコープ)で変数「id」を指定しても害はありません。idとにかく、ビルトインを使用する人はほとんどいません。とはいえ、同僚listがローカル変数を使用して組み込みをオーバーライドした場合、しばらく時間がかかりました。したがって、他の人々が言及する一般的なルールは、まだ理にかなっています。
silviot 2012

5

組み込み関数にちなんで変数に名前を付けるのはよくありません。その理由の1つは、名前がオーバーライドされていることを知らない読者を混乱させる可能性があるためです。


2

idPythonの組み込み関数です。に値を割り当てるidと、関数がオーバーライドされます。のようにプレフィックスを追加するかsome_id、のように別の大文字で使用することをお勧めしIDます。

組み込み関数は単一の引数を取り、CPythonで渡したオブジェクトのメモリアドレスの整数を返します。

>>> id(1)
9787760
>>> x = 1
>>> id(x)
9787760

2
クラス属性またはメソッドに 'id'という名前を付けることができることに注意してください。組み込み関数には影響しません。
ToniRuža


0

他の人は混乱を招くと述べましたが、その理由を詳しく説明したいと思います。これは実話に基づいた例です。基本的に、私はidパラメーターを取るクラスを作成しますが、id後で組み込み関数を使用しようとします。

class Employee:
    def __init__(self, name, id):
        """Create employee, with their name and badge id."""
        self.name = name
        self.id = id
        # ... lots more code, making you forget about the parameter names
        print('Created', type(self).__name__, repr(name), 'at', hex(id(self)))

tay = Employee('Taylor Swift', 1985)

予想される出力:

Created Employee 'Taylor Swift' at 0x7efde30ae910

実際の出力:

Traceback (most recent call last):
  File "company.py", line 9, in <module>
    tay = Employee('Taylor Swift', 1985)
  File "company.py", line 7, in __init__
    print('Created', type(self).__name__, repr(name), 'at', hex(id(self)))
TypeError: 'int' object is not callable

え?どこでintを呼び出そうとしていますか?それらはすべて組み込みです...

badge_idまたはと名付けてもid_、この問題はなかっただろう。


-6

Pythonは動的言語であるため、通常、変数と関数に同じ名前を付けることはお勧めできません。id()はPythonの関数であるため、idという名前の変数を使用しないことをお勧めします。それを念頭に置いて、それはあなたが使うかもしれないすべての関数に適用されます...変数は関数と同じ名前を持つべきではありません。


3
「Pythonは動的言語であるため、変数と関数に同じ名前を付けることは通常お勧めできません。」-変数と関数に同じ名前を付けることはできません。それが動的言語であることとは何の関係もありません。プロパティに同じスコープ内の他のオブジェクトと同じ名前を付けるつもりなら、私も同意しません。「Key」と呼ばれるクラス、「key」と呼ばれるそのクラスのインスタンス、および「key」と呼ばれる別のオブジェクトのプロパティ(「door.key」など)がある場合があります。
Purrell
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.