[Python] 判斷是否有來自標準輸入的內容傳入

一個處理資料的 CLI command 一定會有資料輸入,而輸入來源可以是檔案,也可以是從標準輸入(Standard Input, STDIN)而來,若需要同時支援標準輸入與指定參數(檔案路徑),則需要判斷輸入來源為何。參數判斷的部分,若是使用 argparse 開發的話,則在呼叫 argparse.add_argument() 時就可以設定好參數,最後呼叫 argparse.parse_args() 時即可得知是否有參數輸入,那標準輸入要如何判斷?

Read more “[Python] 判斷是否有來自標準輸入的內容傳入”

發表留言

[Python] 標準串流控制(STD-IN、STD-OUT、STD-ERR)

標準串流(Standard Streams) 是作業系統底層的一個資料交換機制,各個 process 處理資料時皆需要透過它進行輸入與輸出資料,舉凡讀取檔案、寫入檔案或鍵盤輸入等都是。在程式開發上雖然各種語言都已經把這層的處理給包裝起來,已經可以應付日常大部分的用途,但有些需求下還是需要直接操作標準串流才能達成(尤其是開發 CLI Utility)。

在 Python 操作標準串流

# 操作標準串流需要透過 sys package,在程式的開頭先 import 進來
import sys

# 讀取單行
sys.stdin.readline()

# 讀取多行
sys.stdin.readlines()

# 迴圈讀取
for line in sys.stdin:
    print(line)

# 將標準輸出從 console 轉到 stdout.log
fh_stdout = open('stdout.log', 'w')
sys.stdout = fh_stdout

# 輸出字串,但是不會在 console 顯示,而是被寫到 stdout.log 這個檔案
print('Test output to ./stdout.log')

# 將標準輸出從 console 轉到 stderr.log
fh_stderr = open('stderr.log', 'w')
sys.stderr = fh_stderr

# 使用 raise 拋出一個 RuntimeError,錯誤訊息會被寫入到 stderr.log
raise RuntimeError('test stderr')

References

30.1. sys — System-specific parameters and functions — Python 3.7.0 documentation

How do you read from stdin in Python? – Stack Overflow

發表留言

[Python] Django – “no module named django.core.management”

利用 django-admin.py 建立一個新專案後,準備要在專案目錄底下用 manage.py 開始做事情時,出現了詭異的錯誤訊息:

python manage.py
Traceback (most recent call last):
  File "manage.py", line 8, in <module>
    from django.core.management import execute_from_command_line
ImportError: No module named django.core.management

錯誤訊息中的大意是找不到 django.core.management 這個 module,利用下面的指令檢查一下 module source:

python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
/usr/lib/python2.7/site-packages

看起來很正常,但是我安裝 Django 時是利用 Python 3 的 pip 裝的,這時候就會有問題了!

以我目前碰過的系統環境,大部分都會預載 Python 2,而 Python 2 與 Python 3 同時存在時,通常 python 指令都是指到 Python 2。

可以輸入 python -V 或是 which python 去確認這件事情:

$ python -V
Python 2.7.14

which python
/usr/bin/python

ls -l /usr/bin/python
lrwxrwxrwx 1 Calos None 16 Jun 18 00:21 /usr/bin/python -> /usr/bin/python2.7

這時候換個方式去使用 manage.py,使用 python3 後就正常:

python3 manage.py

Type 'manage.py help <subcommand>' for help on a specific subcommand.

Available subcommands:

[auth]
    changepassword
    createsuperuser

[django]
    check
    compilemessages
    createcachetable
    dbshell
    diffsettings
    dumpdata
    flush
    inspectdb
    loaddata
    makemessages
    makemigrations
    migrate
    runfcgi
    shell
    showmigrations
    sql
    sqlall
    sqlclear
    sqlcustom
    sqldropindexes
    sqlflush
    sqlindexes
    sqlmigrate
    sqlsequencereset
    squashmigrations
    startapp
    startproject
    syncdb
    test
    testserver
    validate

[sessions]
    clearsessions

[staticfiles]
    collectstatic
    findstatic
    runserver

這時候我們可以確定是版本造成的問題,那如果想要變更 python 指令使用的版本,只要將現有的 /usr/bin/python 刪掉後,重建連結指到 python3 去即可:

rm -f /usr/bin/python
ln -s /usr/bin/python3 /usr/bin/python

這時候確認版本可以看到 python 指令執行的是 python 3

python -V
Python 3.6.4

Reference: python – Django – no module named django.core.management – Stack Overflow

發表留言