このガイドでは、よくあるPythonの構文エラー、事前に防ぐために使用すべきプロアクティブな戦略、そして効率的に解決するために使用すべきリアクティブな方法について解説します。
Python Interpreter はPythonコードを実行し、機械語に翻訳します。構文ルールに違反すると実行が停止し、トレースバック付きのエラーメッセージが表示されます。
構文エラーは、言語における文法ミスに似た、構造上の誤りから発生します。たとえばPythonでは、if 文やループなどのブロックに対して正しいインデントが必要です。
プログラム実行中に発生するランタイムエラーとは異なり、構文エラーは実行そのものを完全に妨げます。
Pythonには多くの構文ルールがあるため、構文エラーはよく発生します。このセクションでは、頻出するいくつかのエラーとその解決方法を取り上げます。
Pythonはコード構造化のために句読点(記号)に依存しています。構文エラーを避けるために、正しい位置に配置され、適切に対応していることを確認してください。
たとえば、丸括弧 (), 角括弧 [], 波括弧 {} は常にペアで使用しなければなりません。開いた場合は必ず閉じる必要があります。
以下の例では、波括弧が閉じられていません。
# Incorrect proxies = { 'http': proxy_url, 'https': proxy_url
これを実行しようとすると、インタープリタは SyntaxError を投げます。
File "python-syntax-errors.py", line 2 proxies = { ^ SyntaxError: '{' was never closed
Pythonインタープリタは、ファイル名、行番号、そしてエラーが発生した箇所を示す矢印を含む詳細なエラーメッセージを提供します。ここでは、'{' was never closed({ が閉じられていない)と指定しています。
この情報があれば、波括弧を閉じることで問題を簡単に特定して修正できます。
# Correct proxies = { 'http': proxy_url, 'https': proxy_url } # Closed a curly bracket
クォート(' または ")もPythonではよく問題になります。多くのプログラミング言語と同様に、Pythonではクォートを使って文字列を定義します。文字列を開くクォートと閉じるクォートは、必ず同じ種類を使用してください。
# Incorrect host = "brd.superproxy.io'
シングルクォートとダブルクォートを混在させると、構文エラーになります。
File "python-syntax-errors.py", line 2 host = "brd.superproxy.io' ^ SyntaxError: unterminated string literal (detected at line 2)
ここでは、インタープリタが2行目で文字列リテラルが終端されていないことを示しています。
# Correct host = "brd.superproxy.io"
文字列にシングルクォートとダブルクォートの両方が含まれる場合は、トリプルクォート(''' または """)で文字列を囲みます。次のようにします。
quote = """He said, "It's the best proxy service you can find!", and showed me this provider."""
カンマは、リスト、タプル、関数引数の項目を区切ります。カンマが欠けていると、予期しないエラーにつながることがあります。
# Incorrect proxies= [ {"http": "http://123.456.789.1:8080", "https": "https://123.456.789.1:8080"} {"http": "http://98.765.432.1:3128", "https": "https://98.765.432.1:3128"} {"http": "http://192.168.1.1:8080", "https": "https://192.168.1.1:8080"} ]
このコードを実行すると、次のエラーメッセージになります。
File "python-syntax-errors.py", line 3 {"http": "http://123.456.789.1:8080", "https": "https://123.456.789.1:8080"} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SyntaxError: invalid syntax. Perhaps you forgot a comma?
エラーメッセージは有用ですが、すべての問題を検出できるとは限りません。カンマの欠落が検出された場合は、周辺のコードに他のカンマ漏れがないかも確認し、正しい構文になっていることを確かめてください。
# Correct proxies = [ {"http": "http://123.456.789.1:8080", "https": "https://123.456.789.1:8080"}, {"http": "http://98.765.432.1:3128", "https": "https://98.765.432.1:3128"}, {"http": "http://192.168.1.1:8080", "https": "https://192.168.1.1:8080"} ]
カンマとは対照的に、コロンは新しいコードブロック(if 文や for ループなど)を開始するために使用されます。
import requests from bs4 import BeautifulSoup # Incorrect response = requests.get('https://example.com') if response.status_code == 200 soup = BeautifulSoup(response.content, 'html.parser') title = soup.title.text print(title) )
コロンを忘れると、次の構文エラーになります。
if response.status_code == 200 ^ SyntaxError: expected ':'
このエラーメッセージからコロンが欠けていることは明確なので、提案されている場所にコロンを追加して修正できます。
import requests from bs4 import BeautifulSoup # Correct response = requests.get('https://example.com') if response.status_code == 200: soup = BeautifulSoup(response.content, 'html.parser') title = soup.title.text print(title)
Python keywords は特定の意味を持つ予約語であり、変数名として使用できません。キーワードのスペルミス、位置の誤り、または省略はエラーの原因になります。
たとえば、requests と pprint モジュールをインポートする際に import キーワードを誤ってスペルミスすると問題が起きます。
# Incorrect improt requests import pprint
このスペルミスにより、インタープリタは次の invalid syntax エラーを発生させます。
File "python-syntax-errors.py", line 2 improt requests ^^^^^^^^ SyntaxError: invalid syntax
エラーメッセージによっては曖昧な場合があり、追加の注意が必要です。このケースでは矢印が requests を指しており、構文エラーが検出された場所を示しています。モジュール名のスペルミスは構文エラーを引き起こさないため、問題は import キーワードのスペルミスである可能性が高いです。
import を修正するとエラーは解消します。
# Correct import requests import pprint
また、from ... import ... 文を次のように間違えることもあります。
import BeautifulSoup from bs4
一見問題なさそうに見えますが、from キーワードは import の前に来る必要があるため、上記コードを実行するとエラーになります。
File "python-syntax-errors.py", line 2 import BeautifulSoup from bs4 ^^^^ SyntaxError: invalid syntax
from と import を入れ替えると解決します。
from bs4 import BeautifulSoup
キーワードの省略は、Pythonでさまざまなエラーを引き起こす可能性があります。この問題は微妙で、欠けているキーワードによって異なるエラーが表示される場合があります。
たとえば、値を返すはずの関数で return キーワードを省略すると、予期しない挙動になることがあります。
def fetch_data(): response = requests.get('https://example.com') soup = BeautifulSoup(response.content, 'html.parser') data = soup.find_all('div', class_='data') # Missing a return statement here data = fetch_data()
これは構文エラーにはなりませんが、関数は期待される結果ではなく None を返します。return キーワードを追加すると、上記コードは修正できます。
def fetch_data(): response = requests.get('https://example.com') soup = BeautifulSoup(response.content, 'html.parser') data = soup.find_all('div', class_='data') return data data = fetch_data()
関数を定義する際に def キーワードを忘れると、構文エラーになります。
# Missing the `def` keyword fetch_data(): response = requests.get('https://example.com') soup = BeautifulSoup(response.content, 'html.parser') data = soup.find_all('div', class_='data') return data data = fetch_data()
上記コードでは、関数名の前にキーワードが必要だとインタープリタが期待するため、構文エラーが発生します。
File "python-syntax-errors.py", line 1 fetch_data(): ^ SyntaxError: invalid syntax
def キーワードを追加すると解決します。
def fetch_data(): response = requests.get('https://example.com') soup = BeautifulSoup(response.content, 'html.parser') data = soup.find_all('div', class_='data') return data data = fetch_data()
条件文で if キーワードを忘れると、インタープリタが条件の前にキーワードを期待するためエラーになります。
import requests from bs4 import BeautifulSoup response = requests.get('https://example.com') # Missing the if keyword response.status_code == 200: soup = BeautifulSoup(response.content, 'html.parser') title = soup.title.text print(title)
File "python-syntax-errors.py", line 6 response.status_code == 200: ^ SyntaxError: invalid syntax
この問題は、if キーワードを含めるだけで修正できます。
import requests from bs4 import BeautifulSoup response = requests.get('https://example.com') if response.status_code == 200: soup = BeautifulSoup(response.content, 'html.parser') title = soup.title.text print(title)
Note: キーワードの欠落は他の種類のエラーも引き起こす可能性があるため、特に注意してください。
Pythonでは、= は代入に、== は比較に使用します。これらを混同すると構文エラーになることがあります。
import requests from bs4 import BeautifulSoup # Incorrect response = requests.get('https://example.com', proxies=proxies) if response = requests.get('https://example.com/data', proxies=proxies): soup = BeautifulSoup(response.content, 'html.parser') data = soup.find_all('div', class_='data') for item in data: print(item.text) else: print("Failed to retrieve data")
前のコードでは、インタープリタが問題の原因を正しく検出しています。
File "python-syntax-errors.py", line 5 if response = requests.get('https://example.com/data', proxies=proxies) ^^^^^^
ここでは、response が request.get() の結果と一致するかをチェックしようとしています。エラーを修正するには、if 文の代入演算子(=)を比較演算子(==)に置き換えてください。
import requests from bs4 import BeautifulSoup # Correct response = requests.get('https://example.com', proxies=proxies) # Change in the following line if response == requests.get('https://example.com/data', proxies=proxies): soup = BeautifulSoup(response.content, 'html.parser') data = soup.find_all('div', class_='data') for item in data: print(item.text) else: print("Failed to retrieve data")
Pythonはインデントによりコードブロックを定義します。不正なインデントはインタープリタがブロック構造を認識できなくなり、IndentationError につながります。
# Incorrect async with async_playwright() as playwright: await run(playwright)
上記の例では、コロンの後のブロック定義にインデントがありません。コードを実行するとエラーになります。
File "python-syntax-errors.py", line 2 await run(playwright) ^ IndentationError: expected an indented block after the with statement on line 1
この問題を修正するには、Pythonの構文ルールに従い、コードブロックを正しくインデントしてください。
# Correct async with async_playwright() as playwright: await run(playwright)
変数名は英字またはアンダースコアで始める必要があり、使用できる文字は英字、数字、アンダースコアのみです。Pythonは大文字と小文字を区別するため、myvariable、myVariable、MYVARIABLE は別物です。
変数名は数字で始められません。以下の例は 1 から始めているため、このルールに違反しています。
# Incorrect 1st_port = 22225
上記コードを実行すると、インタープリタは SyntaxError を発生させます。
File "python-syntax-errors.py", line 2 1st_port = 1 ^ SyntaxError: invalid decimal literal
修正するには、変数名を英字またはアンダースコアで開始する必要があります。以下のいずれかで対応できます。
# Correct first_port = 22225 port_no_1 = 22225
関数を定義するには、def キーワード、関数名、丸括弧、コロンを使用します。関数を呼び出すときは、関数名の後に丸括弧を付けます。これらの要素のいずれかを省略すると、構文エラーになります。
import requests from bs4 import BeautifulSoup # Incorrect def fetch_data response = requests.get('https://example.com') soup = BeautifulSoup(response.content, 'html.parser') data = soup.find_all('div', class_='data') return data # Incorrect data = fetch_data
この例では、要素の欠落により複数の構文エラーが発生しています。修正するには、関数定義の fetch_data の後に丸括弧とコロンを追加し、最終行の関数呼び出しにも丸括弧を追加してください。
import requests from bs4 import BeautifulSoup # Corrected def fetch_data(): response = requests.get('https://example.com') soup = BeautifulSoup(response.content, 'html.parser') data = soup.find_all('div', class_='data') return data # Corrected data = fetch_data()
関数定義で丸括弧やコロンが欠けると、常に構文エラーになります。一方で、関数呼び出し(fetch_data())で丸括弧を忘れても例外が発生しない場合があり、予期しない挙動につながる可能性があります。
エラーのないコードを書くことは、練習とともに身に付くスキルです。以下のベストプラクティスを理解して実装することで、よくある構文エラーを回避できます。
構文エラーへの最善の対処方法は、事前に防ぐことです。プロジェクトを始める前に、その言語で最も一般的な構文ルールを把握しておいてください。
優れたコードエディタは、シンタックスハイライトやインデントチェックなどの機能により構文エラーの回避に役立ちます。これらのツールは、コードを実行する前に問題を発見できます。
たとえば、エディタ上の赤いマークは、if response.status_code == 200 にコロンが欠けていることを示している可能性があります。
A red mark suggesting there is an error
一貫性は、クリーンでエラーのないコードを書くための鍵です。一貫したスタイルに従うことで可読性が向上し、エラーを見つけやすくなります。
Pythonでは、PEP 8 Style Guide が標準であり、変数命名、インデント、空白の使い方などに関するガイドラインを提供しています。
コードを小さく明確に定義された関数に分割すると、管理性とデバッグ性が向上します。各関数は単一で明確な目的を持つべきです。多くの処理を詰め込みすぎた関数は理解やデバッグが難しくなります。
たとえば、scrape_and_analyze() 関数を考えてみてください。
import requests from bs4 import BeautifulSoup from textblob import TextBlob def scrape_and_analyze(): url = "https://example.com/articles" response = requests.get(url) soup = BeautifulSoup(response.content, "html.parser") titles = soup.find_all("h2", class_="article-title") sentiments = [] for title in titles: title_text = title.get_text() blob = TextBlob(title_text) sentiment = blob.sentiment.polarity sentiments.append(sentiment) return sentiments print(scrape_and_analyze())
この例では、より読みやすくするために、この関数を複数の小さな関数に分割し、それぞれがより小さく管理しやすいコード部分を実行するようにしたほうがよいです。
import requests from bs4 import BeautifulSoup from textblob import TextBlob def scrape_titles(url): """Scrape article titles from a given URL.""" response = requests.get(url) soup = BeautifulSoup(response.content, "html.parser") titles = soup.find_all("h2", class_="article-title") return [title.get_text() for title in titles] def analyze_sentiment(text): """Analyze sentiment of a given text.""" blob = TextBlob(text) return blob.sentiment.polarity def analyze_titles_sentiment(titles): """Analyze sentiment of a list of titles.""" return [analyze_sentiment(title) for title in titles] def scrape_and_analyze(url): """Scrape titles from a website and analyze their sentiment.""" titles = scrape_titles(url) sentiments = analyze_titles_sentiment(titles) return sentiments url = "https://example.com/articles" print(scrape_and_analyze(url))
最善を尽くしても、エラーは発生することがあります。Pythonは問題の内容と場所を示すエラーメッセージを提供します。
Pythonのエラーメッセージは、問題の内容と場所に関する詳細を提供します。注意深く分析することで、問題を特定して解決策を見つけやすくなります。
print() 文を使うと、実行フローを追跡したり、小規模プロジェクトで変数値を確認したりできます。素早いデバッグには有用ですが、セキュリティおよびパフォーマンス上のリスクがあるため、本番環境では使用すべきではありません。
複雑な問題や大規模なコードベースでは、デバッガのほうが効果的です。デバッガを使うと、ブレークポイントの設定、ステップ実行、複数の関数呼び出しにまたがる変数の検査が可能になり、より制御されたデバッグプロセスを実現できます。
難しいエラーで行き詰まった場合は、遠慮なく助けを求めてください。Python Docs や Real Python などのオンラインリソースは有用なガイダンスを提供しています。r/Python、r/LearnPython、Stack Overflow、Python Forum といったコミュニティは、回答や解決策を見つけるのに最適な場所です。
信頼性の高いプロキシサービス、自動化されたデータ収集、すぐに使えるデータセット、またはWebスクレイピングタスクの自動化が必要な場合でも、Bright DataはWebスクレイピングプロジェクトをより効率的かつ生産的にするためのソリューションを提供しています。PythonでWebスクレイピングを学びたいですか?詳細なステップバイステップのPythonスクレイピングガイドをお読みください。
今すぐサインアップして、ニーズに合った適切なプロダクトを見つけ、無料トライアルを本日開始してください!