keep-loving-pythonのブログ

Pythonを愛し続けたいです(Pythonが流行っている限りですが。。。)

⭐重要。解決。stdoutが何かにリダイレクトされているか、調べる方法。pythonスクリプトで。

背景

pythonpythonとして動かすときはいいけれど、
開発環境の中で、それを構成するツールというか、言語として利用される場合、
pythonコード内のログやprintの出力先が、よくわからない場合がある。

解決策

ChatGPTに教えてもらった

Q

stdoutが何かにリダイレクトされているか、調べる方法。pythonスクリプトで。

A

Python スクリプト内で、stdout(標準出力)がターミナル(コンソール)ではなく、ファイルやパイプにリダイレクトされているかどうかを調べる方法はいくつかあります。

以下に、最もよく使われる方法を紹介します。


✅ 方法:sys.stdout.isatty() を使う

import sys

if sys.stdout.isatty():
    print("stdout はターミナル(tty)に接続されています。")
else:
    print("stdout はファイルやパイプなどにリダイレクトされています。")

🔍 解説:

  • isatty() は「これはターミナルか?」という意味で、

    • True → ターミナルに出力されている(リダイレクトされていない)
    • False → ファイルやパイプなどにリダイレクトされている

🔧 補足:出力先のファイル名やデバイス名を確認したい場合

sys.stdout.fileno()os.ttyname() を組み合わせることで、出力先がどこなのかも調べられます(リダイレクトされていないときのみ有効)。

import sys
import os

try:
    ttyname = os.ttyname(sys.stdout.fileno())
    print(f"stdout は {ttyname} に出力されています。")
except OSError:
    print("stdout はファイルまたはパイプにリダイレクトされています。")

💡 応用:printとログの両方に出力するには?

リダイレクトされていると分かったら、print() の代わりに、ログとターミナル両方に出したいなら以下のようにします:

import sys
import logging

logging.basicConfig(level=logging.INFO)

def log_and_print(message):
    logging.info(message)
    print(message, file=sys.__stdout__)  # 元のstdoutを使って出力

log_and_print("これは両方に出力されます。")

必要に応じて、より詳細な出力先チェックも紹介できます。

コメント

以下がよかった。
ビックリした。

import sys

if sys.stdout.isatty():
    print("stdout はターミナル(tty)に接続されています。")
else:
    print("stdout はファイルやパイプなどにリダイレクトされています。")

記事『一発で素人だとばれるPythonコード、「a=1」のどこがまずいのか』について、自分とChatGPTで考えてみた。

元記事

xtech.nikkei.com

自分とChatGPTのやりとり

ワタシ

pythonで、 a=1 とか書くと、素人らしい。 何が問題か、ちょっと、わかりませんが、、、 変数名のつけ方だとしたら、そうかもしれませんが、コードのローカルな部分では、ありじゃないかと思います。それ以外だと、=の前後に半角スペースがないこと。 なんなんでしょう。

ChatGPT

とても良い問題意識です。「a = 1 のような書き方が“素人っぽい”とされる理由」には、いくつかの観点があります。実際には状況によっては問題ないものなので、その“違和感”の正体を整理してみましょう。


✅ なぜ a = 1 が「素人っぽい」と言われることがあるのか?

1. 変数名が意味を持たない(a など)

  • 実用的なコードでは、a のような 意味のない短い変数名は避けられがちです。
  • 特に関数外や広いスコープで a を使うと、保守性や可読性が悪くなるためです。
# 悪い例
a = 1

# 良い例
user_count = 1

🔹 ただし、一時的・局所的な用途(ループ変数など)では i, x, a のような名前は十分許容されます。


2. PEP 8(Pythonのスタイルガイド)に沿っていない可能性

  • a=1 のように**= の前後にスペースがない**のは、PEP 8 に反しています。
# PEP 8 に反する(素人っぽい印象を与える)
a=1

# PEP 8 に従った正しい例
a = 1

3. コンテキストがない(意図が見えない)

  • 単に a = 1 だけ書かれていると、「何をしようとしてるの?」とコードの意図が見えないことが、素人っぽく見られる原因かもしれません。

4. “写経”っぽさがある

  • チュートリアルでよく出てくるコード(例:a = 1, b = 2, print(a + b))は、学習中にありがちなので、「経験者が本気で書いたコードには見えない」印象を持たれがちです。

✅ でも実際には悪くない場面も多い

👍 OKな例(短くても合理的)

for a in range(3):
    print(a)

↑ 一時的でスコープが狭い変数なので a でも良い。


✅ まとめ:素人っぽく見える主な理由

理由 解説
意味のない変数名 a だけだと意図が読めない
スタイルが悪い a=1 のようにスペースがない
コンテキスト不足 どういう目的か分かりにくい
学習初期の定番コード 経験者は避けがち

🔧 改善ポイント

  • ロジックに意味のある変数名を使う
  • PEP 8 を守る(特にスペースやインデント)
  • コンテキストに応じて名前と構造を選ぶ

もし、実際に書いたコードで「これ、素人っぽいかな?」と気になる例があれば、それを教えてくれれば具体的にアドバイスできますよ!

ワタシ2

自分で1個付け足すと、非常に狭い範囲でも、見落とし防止で検索をかける場合があり、一文字は、厳しいというのがあると思いました。

ChatGPT2

おっしゃるとおりです。それはとても鋭い視点で、実務的にも一文字の変数名には見落としのリスクがあるというのは、非常に有効な指摘です。


🔍 なぜ一文字の変数が検索性に弱いのか

✴️ 検索の誤ヒット・ノイズが多すぎる

たとえば ax などを検索しようとしても:

  • 関係ない単語(data, max, example, など)にもヒットする
  • 他の変数や文字列リテラルにも紛れる
  • Pythonの標準出力 print(a) などが多すぎて本当に見たい箇所が埋もれる

🔧 検索に強いコードにするために

✅ たとえスコープが狭くても、2文字以上か意味を持つ名前にすることが推奨されます。

# 弱い例(検索しづらい)
a = get_value()

# 強い例(検索しやすく意図が明確)
val = get_value()

プレフィックスや用途別命名も効果的

# 一時ファイル名なら temp_file
temp_file = open("tmp.txt", "w")

💡 一文字変数が許される主な例(慣習的)

変数名 用途
i, j, k 数値ループインデックス
x, y 数学的/図形的な座標
f 一時ファイル/関数名(ただし文脈次第)

それ以外で a, b, c などを使うと、検索性・保守性の面で損をします。


✅ まとめ

あなたの指摘「検索性の観点から一文字変数は危険」は、現場でも非常に有効です。 狭いスコープでも予期しないバグや見落としを防ぐには、わずか数文字でも意味のある名前をつけることが、後の自分やチームを助けます。

良い気づきでした!


答え合わせ

答えは、会員しか見えないので、わからないですが。

公開されている範囲で、

 最近、約10年前に自分が雑誌に書いたPythonのサンプルコードを別の媒体に流用する作業をしていた。そのコードでは「a=1」といったように、「=」の前後を詰めて書いていた。

となっていた。 引用元: https://xtech.nikkei.com/atcl/nxt/mag/nc/18/052100112/051600119/

また、以下では、もう少し、長い記述が公開されていた。

xtech.nikkei.com

まとめ

あまり外してはいない気がした。わかりませんが。。。

解決策。fatal: Authentication failed for 'https://github.com/XXXGhidorah/saisyo.git/'

解決策(いまどき。2024、11月。)

エラーメッセージをChatGPTに貼り。どうしよう?、と聞く!

解決策。(ChatGPTまま)

GitHubでは、2021年8月13日以降、パスワード認証が廃止され、代わりに Personal Access Token (PAT) を使った認証が求められています。以下の手順でトークンを設定して再度プッシュを試みてください。

1. Personal Access Token (PAT) の作成

GitHubにログインした状態で、以下の手順でトークンを作成します。
1. GitHubの右上のプロフィールアイコンをクリックし、「Settings」を選択。
2. 左メニューから「Developer settings」を選択。
3. 「Personal access tokens」を選択し、「Tokens (classic)」をクリック。
4. 「Generate new token」をクリック。
5. 必要なスコープ(アクセス許可)を選択します。通常、repo(リポジトリ関連)を選択すれば十分です。
6. トークンを生成し、そのトークンをコピーします(トークンは後で再度表示できないので、必ずコピーして保存してください)。


2. GitにPATを設定

次に、Gitでリモートリポジトリにプッシュする際に、新しいトークンを使って認証を行います。
1. リモートURLを更新する
既にhttps://github.com/username/repository.git の形式でリモートリポジトリにアクセスしていますが、https://<GitHubのユーザー名>:<PAT> を使って新しい形式に変更します。
bash
コードをコピーする
git remote set-url origin https://GitGhidorah:<Your-PAT>@github.com/GitGhidorah/saisyo.git
Your-PATの部分には、先程コピーしたPersonal Access Tokenを貼り付けてください。
2. 再度プッシュを実行
トークンを設定したら、再度プッシュを実行します。
bash
コードをコピーする
git push origin branch1st


3. GitHubにログインしてプッシュが成功することを確認

これで、Personal Access Tokenを使って認証され、プッシュが成功するはずです。
もし、別の方法での認証(SSH認証など)を希望する場合は、SSHキーを使った方法もあります。その場合は、また教えてください。

解決策。 pythonを実行したら、「 Python 」とだけ1行表示される。

エラー

C:\_work\_yyyyy_GYOMU\hatena\word2pdf\_sample_2nd>python docx2md.py
Python

環境

windows11

解説策

たぶん、pythonがインストールされていない(PCを変えたとか。。。)が原因なので
pythonをインストールする。

Wifi環境のWindowsPC2台の環境で、redmineを使う(接続する)。hostnameにて。

解決策

redmineが入っている側のPCのhostnameを確認

C:\Users\XYZZ2>hostname
laptop-acg7buuu

アクセス方法

http://laptop-acg7buuu.local:81/redmine/

make時のエラーの見方(基本1) 例:block.c:2:10: fatal error: curses.h: No such file or directory

make時のエラーの例

XYZZ@LAPTOP-ACG7BUHI:~/_Makekana/_block$ make
cc    -c -o block.o block.c
block.c:2:10: fatal error: curses.h: No such file or directory
    2 | #include <curses.h>
      |          ^~~~~~~~~~
compilation terminated.
make: *** [<builtin>: block.o] Error 1

エラーの見方

端的には、以下のファイルがincludeとして探す範囲にないというだけ。

#include <curses.h>

エラーの再現方法

全然メリットないが、、、、

ChatGPTによると、以下で再現できる。

echo '#include <curses.h>' | cc -E -

解決策

これは、curses.hが入るようなライブラリがインストールできてなかっただけ。

import fitz (変な動きするな。。。。)

変な動きとは

import fitz

print("only-import")
print("i am a org.py")

実行結果

C:\_add_page>python fitz-test.py
i am a org.py
only-import

C:\_add_page>

なんと、org.py が実行されます!!!!