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

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

ただいまの
回答率

88.93%

Pythonのオブジェクトのプロパティはなぜクォートで囲む必要があるのか?

解決済

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 234

611olj

score 7

Pythonでは
a = {'v': 3}とは書けますが
a = { v: 3 }とは書けません。
JavaScriptでは書けるのに。

なんでなんでしょうか?

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • 611olj

    2020/07/14 10:02

    コード書いてくれてありがとうございます。
    const v = 'key';
    const data = {};
    data[v] = 123;
    console.log(data); ({key: 123}と出力されます)

    data = {}; と初期化する必要があり、手間ですね。

    キャンセル

  • shiracamus

    2020/07/14 11:26 編集

    const v = "key";
    const data = { [v]: 123 };

    と書くこともできます。
    JavaScriptでは、文字列をキーにする場合はダブルクオートで囲まない(囲ってもいい)、変数の内容をキーにする場合は角括弧で囲む。
    Pythonでは、文字列をキーにする場合はダブルクオートで囲む、変数の内容をキーにする場合は何も囲まない。
    どっちが手軽か、分かりやすいか、人それぞれ意見があると思いますが、言語仕様としてどちらかに決められています。

    キャンセル

  • 611olj

    2020/07/14 11:37

    >const data = { [v]: 123 };
    こんな書き方あるんですね。

    勉強になります。ありがとうございます。

    キャンセル

回答 2

checkベストアンサー

+4

まず前提として、javascriptにおけるa = { v: 3 } というのはjavascriptのオブジェクトに関係している一方、
pythonにおける a = { v: 3 } というのはpythonの辞書に関係しており、書き方は似ていますが別物です。

そのうえで質問者さんの問題を整理すると、
1. javascriptでは、初出の文字vに関して
var a = { v: 3 };
を実行しても特にエラーが出ませんが、

2. pythonでは未定義の変数vに対して
a = {v: 3}
を実行すると、
NameError: name 'v' is not defined

というエラーが発生する。これはなぜか?という質問だと把握しました。

ただ、pythonでも、can110さんが結果を書いているように

v = "keystr" # <=文字列なら何でもいいです。
a = {v: 3}

w = 100       # <=整数でもOK
b = {w: 50}


というように、先に名前(変数)を定義しておけば、javascriptと同じように書いてもエラーが出ません
(なお、必ずエラーが出ないわけではなく、辞書のキーは、文字列やタプルなど「hashableなものでなければならない」という条件があります)

なぜこのような違いが生じるかですが、ぶっちゃけていうと、言語が異なるから、ということになるでしょう。

でもこれだと回答にならないので、以下は推測を交えて説明します。

javascript:「オブジェクト」との関係、ラクに速くスクリプトを書けること

javascriptにおけるa = {v: 3}というのは、オブジェクトに対するプロパティの定義です。
これは

var a = new Object();
a.v = 3;


というように、オブジェクトを作ってから、vというプロパティに値を代入する形でも書けます。

javascriptでオブジェクトのプロパティに使用できるのは、一定の条件に該当する識別値か、引用符で囲まれた文字列、もしくは数値に限られるようです。(間違っていたらすみません)

そして、プロパティ位置に置かれた識別値や数値は、引用符で囲まなくても、自動的に文字列として解釈されるようです。(※「1st_key」のように先頭が数字になっているものや途中に空白があるもの等は引用符を省略できません)
つまり{v: 3} と書くと {"v": 3} と書いたものとして解釈されます。
var v = "keystr"
としたあとで
var a = {v:3};としても
aは{"keystr": 3} ではなく、 {"v": 3} になります。

javascriptでは、わざわざ引用符を書かなくてもプロパティ位置に指定されたものを文字列として扱うことで、引用符を書く手間をなくしている(と私は推測しています)

たった「"」2回といえど、何行も書くとなると結構時間の無駄になりますよね?
引用符のペアをそろえていないとエラーになりますし、

var myBox = new Object;
myBox = {front: {color: {type: 'high', 'code': '#ffffff'}}};


というように、プロパティを引用符なしで定義でき、

c = myBox.front.color.code;


と引用符なしでプロパティにアクセスできるのは便利です。

(pythonで外部ライブラリを使わず普通に辞書を使うとなると

myBox = {"front": {"color": {"type": "high", "code": "#ffffff"}}}
c = myBox["front"]["color"]["code"]


とする必要があります)

python:プログラムとしての直感性・柔軟性

上の例では、pythonでは一度定義した変数であれば、任意に辞書のキーとして指定できるように見えます。
(繰り返しますが「hashableなものしかキーにできない」という制約はあります)

そのかわり、javascriptと異なり、未定義の変数に該当する文字列を文字列としてのキーに指定する場合は必ず引用符で囲まなければなりません。(でなければ上記のようにNamedErrorが出てしまいます)
pythonの辞書はjavascriptのオブジェクトに比べると、記述に手間がかかる・・・?

でも、この「変数を辞書のキーとして指定できる」という仕様は、メリットもあると思います。

プログラミングをやっている立場からすれば、引用符で囲まれていないものは、中身が必ずしも文字列とは限らないというのは日常茶飯事です。
javascriptの例のように 
var v = "keystr" としたあとで a={v:3}としたら
aは{"keystr":3} ではなく、 {"v":3}‘となってしまうのは、直感に反するような気がしませんか?

辞書のキーに(hashableなものに限りますが)変数を指定できるからこそ

if 64 < i < 64 + 26 + 1:
  a = {chr(i): i}
else:
  a = {"DUMMY": 0}


とか

s = {chr(i): i for i in range(65, 65 + 26)} 
>>> print(s)
>>> {'A': 65, 'B': 66, 'C': 67, 'D': 68, 'E': 69, 'F': 70, 'G': 71, 'H': 72, 'I': 73, 'J': 74, 'K': 75, 'L': 76, 'M': 77, 'N': 78, 'O': 79, 'P': 80, 'Q': 81, 'R': 82, 'S': 83, 'T': 84, 'U': 85, 'V': 86, 'W': 87, 'X': 88, 'Y': 
89, 'Z': 90}


のような柔軟なプログラミングが可能になります。

※もちろんjavascriptでも、

var a = new Object();
var k = 'DUMMY';
a[k] = 0; //a['DUMMY'] = 0; または a.DUMMY = 0; と同じ


というように、連想配列を使うことで同じようなことはできます。

pythonでも、attrdictという外部ライブラリを使うことで、辞書をドットでアクセスすることは可能です。

以上、つらつらと書きましたが、あくまで私自身の推測によるところが大きいですので、もっと深遠な理由があるやもしれません。

参考にしたもの:
MDN オブジェクトでの作業
Python における hashable
連想配列を使ったプロパティへの値の代入と参照
Pythonで辞書のキーにtupleが指定できた件(+パフォーマンスの話)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/10 22:00

    詳細な回答ありがとうございます。
    回答のPythonの説明の箇所の理解がいまいちです。
    勉強してまた見直そうとおもいます。

    キャンセル

0

Pythonでも書けます。

(base) C:\Users\user\desktop>python
Python 3.7.6 | packaged by conda-forge | (default, Jun  1 2020, 18:11:50) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> (略)
>>> a = { v: 3 }
>>> print(a)
{'v': 3}
>>>

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/10 21:58

    あ、書けるんですね。ありがとうございます。

    キャンセル

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

  • ただいまの回答率 88.93%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る