このPythonスニペットでセミコロンが許可されているのはなぜですか?


166

Pythonでは、ステートメントを終了するためにセミコロンを使用することは保証されていません。では、なぜこれが(以下で)許可されるのでしょうか。

import pdb; pdb.set_trace()

1
このようなコードはあからさまにデバッグ目的でのみ使用され、おそらく「実行」される前に削除されることに注意してください。私はあなたが持っているのと同じようにそのスニペットを使用するので、簡単に移動できます。
Nick T

Lol私は同じウェブサイトからこの質問に来ました:realpython.com/python-debugging-pdb
mackycheese21

回答:


225

Pythonはステートメントを終了するためにセミコロンを必要としません。複数のステートメントを同じ行に配置する場合は、セミコロン使用してステートメントを区切ることできます。

さて、なぜこれが許可されるのですか?それは単純な設計決定です。Pythonがこのセミコロンのことを必要としているとは思いませんが、誰かがそれを持っているといいと思い、それを言語に追加しました。


16
それは次のようなものに役立ちますtimeit a = 5; a*a
エンドリス2013年

13
これは、execステートメントに役立つようです。たとえば、exec( 'for a [1,2,3]:print a; print a + 1')
Phil C

75
私はC、Obj-C、Javascript、PHPの背景を持つPythonに来ました。(役に立たない)ターミネータを頻繁に使用します。行の終わり。しかし幸いにもPythonは私を許してくれます
Paolo

36
セミコロンは、djangoシェルまたはデバッガーで非常に便利です。そのため、小さなプログラムを1行で記述して、後で繰り返すことができます。
ブライス2013年

5
@endolithどういうtimeit意味ですか?まだ2 a = 2; a*aなので、役に立たないa。それはでなければなりませんa = 2; a *= a
Nearoo

58

http://docs.python.org/reference/compound_stmts.html

複合ステートメントは、1つ以上の「句」で構成されます。句は、ヘッダーと「スイート」で構成されます。特定の複合ステートメントの節ヘッダーは、すべて同じインデントレベルにあります。各句のヘッダーは、一意に識別するキーワードで始まり、コロンで終わります。スイートは、文節によって制御されるステートメントのグループです。スイートは、ヘッダーと同じ行にあり、ヘッダーのコロンに続く、セミコロンで区切られた1つ以上の単純なステートメントにすることも、後続の行にある1つ以上のインデントしたステートメントにすることもできます。ネストされた複合ステートメントを含めることができるのは、スイートの後者の形式のみです。次の例は違法です。主な理由は、次のelse節がどのif節に属しているかが明確でないためです。

if test1: if test2: print x

また、このコンテキストではセミコロンはコロンよりも強く結合するため、次の例では、すべての印刷ステートメントが実行されるか、まったく実行されないかのいずれかになります。

if x < y < z: print x; print y; print z 

要約:

compound_stmt ::=  if_stmt
                   | while_stmt
                   | for_stmt
                   | try_stmt
                   | with_stmt
                   | funcdef
                   | classdef
                   | decorated
suite         ::=  stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT
statement     ::=  stmt_list NEWLINE | compound_stmt
stmt_list     ::=  simple_stmt (";" simple_stmt)* [";"]

4
ifの後のセミコロンの優先順位がコロンよりも低いことを知りませんでした。ありがとう!
2014年

3
@gaborous私は個人的にあなたのコメントがあいまいだと感じて、あなたが他の方法を意味するのではないかと思いました。だから、明確にするために、私はむしろして、他の読者を示唆しているという点で:公式のフレーズにこだわるif cond: stmt1; stmt2; stmt3たとえば、いずれかの全部またはステートメントのいずれもが「実行されます。
RayLuo

そうです、優先度が低い場合、すべてのセミコロンステートメントが実行されるまで、レクサーは親(コロン)ブロックを離れることができません。それは本当に明白なことではありません。
16年

38

Pythonは、;ターミネータではなく、セパレータとして使用します。それらを行の最後で使用することもできます。これにより、ステートメントのターミネーターのように見えますが、これはPythonで空白のステートメントが有効であるためにのみ有効です-末尾にセミコロンを含む行は2つのステートメントで、2番目1つの空白。


28
セミコロンを最後(またはどこかに)に置くと、SyntaxErrorが発生します。したがって、空白のステートメントは完全に合法ではないようです。
Cucu 2013

10
おそらくそれはリスト、タプル、末尾のコンマ付きのdictsと同じロジックを持ち、それらのトリミングされた対応物(例えば[1,2,3] == [1,2,3、])と同じですが、二重のコンマを含むことはできません。したがって、基本的にPythonには「末尾の空白のリムーバー」があります。ちなみに、これはstmt_list ::= simple_stmt (";" simple_stmt)* [";"]
これから

@Cucuそうです。また、セミコロンで行を開始したり、コンマで式リストを開始したりすることもできません。したがって、セミコロンとコンマはセパレータであり、オプションのターミネータであると言う方がより正確です。
wjandrea

28

通訳のセミコロン

答えを読んでも、セミコロンを使用することの1つの重要な側面、おそらくそれが本当に違いをもたらす唯一の側面を見逃しています...

インタープリターREPL(Pythonインタラクティブシェル、IDLE、ipython)で作業している場合、最後の式の値が画面に表示され、通常これが意図された動作です。

副作用のための式の使用

ただし、式の副作用のみを評価したい場合もあります。たとえば、 matplotlibた。

この例では、あなた(おそらく)が1画面表示させたくないreprのS matplotlib時々の呼び出しによって返されたオブジェクトmatplotlibの機能と、少なくともIPythonで、あなたが持っている可能性の一つはにセミコロンを追加することで、過度に冗長二つの式、によって構成されるようステートメント、今IPythonは、入力されたラインを見matplotlib化合物式の値であるように、呼び出し及びヌル文Noneと何もインタプリタ(他の可能性があることによって、画面に出力されていない割り当てのように、_ = plot(...)しかし、私はそれがもう少し煩わしいと思います)。

個人的な発言

私見、セミコロンを使用してインタープリターで不要な出力を抑制することは、IPytonノートブックの導入に伴い、ドキュメントと最終的な再利用のためのインタープリターセッションの入力と出力(グラフィック出力を含む)を保存できるようになりました。 。


共有してくれてありがとう!これはちょうど私の問題を正確に解決しました。セミコロンはipythonノートブックのmatplotlibによってreprを防ぐことができます
Napitupulu Jon

これはIPythonのみの機能であり、nullステートメントではなく、特別な構文です。
wjandrea

@wjandrea正解です。ただipython...私はあなたの発言を反映するように私の回答を編集しました。
gboffi

12

他の誰もが指摘したように、セミコロンを使用してステートメントを区切ることができます。あなたは持っていませため、それはいつものスタイルではありません。

なぜこれが便利なのかについて、一部の人々は2つ以上の非常に些細な短いステートメントを1つの行に置くことを好みます(個人的には、これにより複数の簡単なスキム行が1つの複雑に見える行になり、それが簡単であることがわかりにくくなります) 。

ただし、を使用してシェルからPython one linersを呼び出す場合は、ほぼ要件ですpython -c '<some python code>'。ここで、インデントを使用してステートメントを区切ることはできないため、1行が実際に2行である場合は、セミコロンを使用する必要があります。また、ワンライナーで他の引数を使用する場合は、でsys取得するためにインポートするsys.argv必要があり、別のimportステートメントが必要です。例えば

python -c "import sys; print ' '.join(sorted(sys.argv[1:]))" 5 2 3 1 4
1 2 3 4 5

2
あなたはできてコマンドを渡すときに、インデントや改行を使用するpythonだけで、複数のラインの上に引用されたコードをまたがるかヒアドキュメントを使用:シェルで。それでも、「ワンライナー」にしたい場合は失敗します。;)
00dani 2014年

レールの答えのための特徴を含んでいる-c
n611x007

6

私は古いCプログラマーとして偏っていることに気づきますが、Pythonのさまざまな規則によって物事を理解するのが難しくなることがあります。私は時々インデントの慣習を少し厄介なものだと思っています。

場合によっては、ステートメントまたはブロックがいつ終了するかを明確にすることが非常に役立ちます。標準Cコードは、次のようなものを読み取ることがよくあります。

for(i=0; i<100; i++) {
    do something here;
    do another thing here;
}

continue doing things;

ここでは、明確にするために空白を使用しています。ループがどこで終了するかは簡単にわかります。

Pythonでは、(オプションの)セミコロンで終了できます。上記のように、実行するステートメントの後に「null」ステートメントが続くという意味ではありません。たとえば、

print(x);
print(y);

と同じです

print(x)
print(y)

最初の行の各行の終わりにnullステートメントがあると思われる場合は、次のようにしてみてください。

print(x);;

構文エラーがスローされます。

個人的には、多くの引数や長い名前の引数を持つネストや関数がたくさんあるときに、コードを読みやすくするためにセミコロンが見つかります。だから、私の目には、これは他の選択肢よりもはるかに明確です:

if some_boolean_is_true:
    call_function(
        long_named_arg_1,
        long_named_arg_2,
        long_named_arg_3,
        long_named_arg_4
    );

私にとって、それは最後の ')'が多くの行にまたがるいくつかの 'ブロック'を終了することをあなたに知らせるからです。

私は個人的には、PEPスタイルのガイドライン、それを実施するIDEで構成されたガイドラインがたくさんあると思います。後者を信じる場合は、数値をフォーマットする方法を見てください。現時点では、Pythonは4異なる方法をしています。

私はいくつかのハードルに悩まされると確信していますが、コンパイラ/インタープリタは、引数が長い名前でも短い名前でも構いません。ただし、Pythonのインデント規則では、空白は関係ありません。コードの最大の問題は、何が起こっているのか、物事の始まりと終わりなどを理解するために、別の人間(さらには数か月の仕事の後の自分)を明確にすることです。



5

「からの引用するとニシキヘビアタック

すべてのステートメントをセミコロンで終了しないでください。これをPythonで行うことは技術的には合法ですが、1行に複数のステートメントを配置しない限り(x = 1; y = 2; z = 3など)、まったく役に立ちません。


4
なんでx,y,z = 1,2,3
Anirban Nag 'tintinmj' 2014

5
@ AnirbanNag'tintinmj 'この特定のケースでx, y, z = 1, 2, 3は、タプルの構築に不必要な往復が発生し、すぐにそれが逆アセンブルされるため、速度が遅くなると思います。(ちなみに、@ communistpancakeがx=1; y=2; z=3パターンを示唆しているとは思いませんが、セミコロンがターミネーターではなくセパレーターの例を示しているだけだと思います。)
RayLuo

1
@AnirbanNag-マルチステートメントラインのごみの例だったからです。
2018年

4

1行に複数のステートメントがある場合、区切り文字としてセミコロンを含めることができます。次に例を示します。http : //docs.python.org/reference/compound_stmts.htmlあなたの場合、ポイントを簡単に挿入してデバッガーに割り込むことができます。

また、Learning Python BookでMark Lutzが述べたように、すべてのステートメントをセミコロンで終了することは技術的には合法です(不必要で厄介ですが)。


2

Pythonでは、1行に複数のステートメントを含める場合、セミコロンを使用してステートメントの終わりを示すことができます。


2

セミコロンは、1行に2つ以上のコマンドを使用できます。使用する必要はありませんが、制限はありません。

セミコロン(;)は、どちらのステートメントも新しいコードブロックを開始しないことを条件として、1行に複数のステートメントを許可します。

http://www.tutorialspoint.com/python/python_basic_syntax.htm


2

セミコロン(ドット、コンマ、括弧など)は、宗教戦争を引き起こす傾向があります。それでも、それら(またはいくつかの類似した記号)は、さまざまな理由で任意のプログラミング言語で役立ちます。

  • 実用的:概念的に同じ行にあるいくつかの短いコマンドを配置する機能。狭い蛇のように見えるプログラムテキストは、改行とインデントによって意図されているものとは逆の効果を持ち、構造を強調しています。

  • 概念:昔は「きれいな印刷」と呼ばれていた、純粋な構文(この場合は一連のコマンド)とプレゼンテーション(たとえば改行)との間の懸念の分離。

観察:構造を強調表示するために、インデントは明白な方法で垂直線によって増加/置換でき、インデントの始まりと終わりを確認するための「視覚的な定規」として機能します。異なる色(たとえば、抵抗器のカラーコードに従う)は、混雑を補う場合があります。


1

著者が許可することを決定したため、許可されています:https : //docs.python.org/2/reference/simple_stmts.html

なぜ著者がそうすることに決めたのかという質問に移れば、セミカラムは少なくとも次の言語で単純なステートメントの終了として許可されているためだと思います:C ++、C、C#、R、Matlab、Perl、...

そのため、他の言語のバックグラウンドを持つ人々のためのPythonの使用に移行する方が速くなります。そして、そのような評判において一般性を失うことはありません。


1

セミコロン( ";")は、次のCコードがある場合など、同じブロック内のステートメントを分離する場合にのみ必要です。

if(a>b)
{
largest=a;  //here largest and count are integer variables
count+=1;
}

Pythonでは、次の2つの形式のいずれかで記述できます。

if a>b:   
    largest=a
    count=count+1

または

if a>b:    largest=a;count=count+1

上記の例では、ifブロック内に任意の数のステートメントを含めることができ、「;」で区切ることができます。代わりに。

上記の説明ほど簡単なものはないことを願っています。


0

ここに存在する膨大な知識に加えて、
これはmatplotlibライブラリに関連する答えです

import numpy as np
import matplotlib as plt
%matplotlib notebook
linear_data = np.array([1, 2, 3, 4, 5, 6, 7, 8])
quadratic_data = linear_data**2
plt.figure()
xvals = range(len(linear_data))
plt.barh(xvals, linear_data, height = 0.3, color='b')
plt.barh(xvals, quadratic_data, height = 0.3, left=linear_data, color='r')

barh(水平バー)の最後にセミコロンを指定しない場合、出力はプロット+関数アドレスになります。ただし、両方のbarh行の終わりにセミコロンを使用すると、プロットのみが表示され、関数アドレスの出力が抑制されます。

このようなもの: 比較


3
これはIPythonに固有のものであり、標準のPython REPLには適用されません。
wjandrea

これは、言語の作者が単純さ、力、均一性を導入していると思っていた方法が、この問題と同じように問題を先取りすることができなかった素晴らしい例だと思います。
eSurfsnake
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.