スポンサーサイト

    上記の広告は1ヶ月以上更新のないブログに表示されています。
    新しい記事を書く事で広告が消せます。

    id関数なんてのがあったんだね

     最近忙しくてブログを全然更新してませんでしたが、GWでちょっぴり心に余裕が出来たんで小ネタでもメモとして残します。(スタチューとかフィギュアは直ぐに記事にするのにね・・・)

     ホントは先月末に可動したガンダムトライエイジ 鉄血の4弾でウイングガンダムゼロ(EW)とガンダムエピオン(EW)やったよ〜〜〜〜〜〜って言うネタをやろうと思ったんだけど、完全に機会を逸してしまった。
     せめて写真だけでも載せとこw
    tryTk04_000.jpg
     いやぁ〜、ココらへんのガンダムが青春真っ只中だった身としては、イラスト担当させて頂いてテンションMAX!! ゼロとエピオンって事で新規2体はなかなか厳しかったけど、やれてホント良かったです❤(ӦvӦ。)


     と、プライベートな話はそろそろ終わりにして、本日のテーマは久しぶりにPythonネタです。
     ちゃんとマニュアルとかクックブックとか読んでる人からしたら常識でしょうが、今回はid関数について。
     Pythonではありとあらゆるものがオブジェクトになっています。
     例えば関数を定義して、その関数を()を付けずに呼ぶとオブジェクトとしての型やメモリアドレスを教えてくれます。
    def testFunction():
        pass
    
    testFunction
    # >> <function testFunction at 0x1006e22a8> 
    
     上の例ではtestFunctionがfunction(関数オブジェクト)であり、それがメモリ上では0x1006e22a8に居ますよって事を教えてくれてる訳です。

     クラスなんかでも同じですね。
    class TestClass(object):
        pass
    
    class_a = TestClass()
    class_a
    
    # >> <__main__.TestClass object at 0x1006d8ed0>
    
     上の場合はTestClassでメモリ上の0x1006d8ed0に居ますよって事を教えてくれてます。
     関数の場合と一緒ですね。
     従って、このメモリアドレスを見れば同じものかどうかが一目瞭然なわけです。
    class TestClass(object):
        pass
    
    class_a = TestClass()
    class_b = TestClass()
    
    class_a
    # >> <__main__.TestClass object at 0x1006e4050>
    class_b
    # >> <__main__.TestClass object at 0x1006e4090>>
    
     このように、変数class_aとclass_bは同じクラスのインスタンスですが、メモリアドレスを見れば別のオブジェクトになっているかどうかがすぐ分かるようになってるわけです。
     シングルトンインスタンスなんかを実装した場合に、ホントにシングルトンになってるかどうかが怪しい場合はこうやってプリントすれば一発な訳ですね!素晴らしい!!


     ところがクラスの__repr__を上書きしてたり、組み込みオブジェクトのリストや文字何かだと同じことをしてもメモリアドレスがわかりません。
    class TestClass(object):
        def __repr__(self):
            return 'I am TestClass!!!'
    
    class_a = TestClass()
    class_a
    # >>I am TestClass!!!
    
    list_b = range(10)
    # >>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    
     何だと・・・?くっ、ゼロよ・・・俺を導いてくれ!



     スイマセン、微妙に冒頭のウイングゼロのネタ引っ張ってます(;´∀`)
     さて、こんな時に登場するのがid関数であります。
    list_b = range(10)
    print(list_b)
    # >>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    
    print(id(list_b))
    # >>4302047712
    
     おぉ〜、何やら数字が帰ってきた〜!!!  実はid関数で帰ってくるこの数字もメモリアドレスになってて、16進数に変換してやればあの形になって帰ってくるのですよ!
    class TestClass(object):
        pass
    
    class_a = TestClass()
    print(class_a)
    # >> <__main__.TestClass object at 0x1006e40d0>
    
    print(hex(id(class_a)))
    # >> 0x1006e40d0
    
     おぉぉ〜、これでlistやdictが同一かどうかを見た目でわかるようになったぞぉ!!!
    a = range(10)
    b = a
    print(id(a))
    # >> 4302148456
    print(id(b))
    # >> 4302148456
    # aとbは同一のリストオブジェクトなのでidも一緒、ってか同一人物。
    
    a[:] = []
    b = []
    print(id(a))
    # >> 4302148456
    # aは内容をクリアしているだけなのでidは変わらない。
    print(id(b))
    # >> 4302148600
    # bは空のリストを入れているので別物にすげ変わってる。なのでidも別。
    
     上の例では、まずaに0〜9までの数字が入ったリストを作成し、それをbへ入れてます。
     なので最初の段階ではidはaもbも一緒ですね。
     ところが、その後aは内容をクリアする処理を、bは空のリストを入れる処理をしています。
     内容をクリアしただけのaは、リストオブジェクト自体は一緒なのでidに変更はありません。
     しかしbの方は空のリストを入れたので、表面上はaと同様空っぽのリストですが、中身は全くの別人になってるわけですね。
     従って、上記のaとbを比較すると
    a == b
    # >> True
    
    a is b
    # >> False
    
     a == bは同じ型で同じ内容かを比較しています。aとbは同じリスト型で、内容は空のリストなんで結果はTrue。
     ところがa is bはaとbが同一のオブジェクトなのかをチェックしてるので、こちらの結果はFalseになるんですね。



     ・・・あれ、listやdictが同一かどうかのチェックするだけなら is でいいじゃん・・・
     ・・・任務完了。自爆する・・・


     ポチっ
    スポンサーサイト

    コメントの投稿

    非公開コメント

    プロフィール

    Eske

    Author:Eske
    萌えイラストレーターを目指す3DCGイラストレーター。
    現在ポケモンカードゲーム、ガンダムトライエイジ、ガンダムコンクエスト、妖怪ウォッチとりつきカードゲームなどで3DCGを使用したイラストレーターとして参加中。

    主にここでは日々気づいたメモなんかを残してます。
    イラストのお仕事も受け付けております。ココからアクセスできますので、お気軽にご相談下さい。

    最新記事
    最新コメント
    カテゴリ
    最新トラックバック
    月別アーカイブ
    検索フォーム
    リンク
    QRコード
    QR
    上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。