LoginSignup
11
11

More than 5 years have passed since last update.

Python で日本語出力

Last updated at Posted at 2016-06-19

はじめに

python を始めようと思って、まあ、そこはやっぱり

print("Hello world")

うん、よしよし。

print("日本語")
Traceback (most recent call last):
  File "/tmp/a.py", line 1, in <module>
    print("\u65e5\u672c\u8a9e");
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)

:cry: :thumbsdown:

普通の解決策

いろいろ、ググッて調べたところ、unicode と byte の変換をしなきゃイカン、ということで

print("日本語".encode("utf-8"))
b'\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e'

いや、だからそうじゃなくてね。

setenv LANG ja_JP.UTF-8
日本語

まあ動いたわけですよ。しかしさらなる問題が!

cron から起動したいんだが

cron 起動する場合は、親プロセスが cron なので、当然 cron の環境を引き継ぐわけです。それは、システム全体としてどういうロケールに設定しているかと言う話。しかし、システム全体は基本 C で統一しているポリシーなので(ls とか date を日本語ロケールフォーマットにされると、いろいろ動かなくなる)、cron の環境も当然 LANG=C なの。それは変えられないの。

余談:shebang

スクリプト起動するために、1行めに #! /usr/local/bin/python3 とか書きますよね。これ、呼び方はいろいろあるんだけど、シェバン(shebang)というらしい。で、これで呼び出されるものは、2重に shebang が使えない。つまり、#! /usr/local/bin/foo のとき、/usr/local/bin/foo の1行めが、#! /usr/local/bin/bar だとダメだ、ということ。知らんかった。たぶんシステムコール中で exec()系列の関数を呼び出しているということなんだろう。

環境変数をセットして起動したい

/usr/local/bin/python3 を、シェルスクリプトにする案は挫折したので、しょうがなく C で書きました。

python3.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char **argv){
  putenv("LANG=ja_JP.UTF-8");
  argv[0] = "/usr/local/bin/python3.5";
  argv[argc] = NULL;
  execv("/usr/local/bin/python3.5",argv);
}

これで、最初の print("日本語") のみで動作するようになりました。(encodeがいらなくなった)

python3 がシンボリックリンクではなくなりましたが、無理やりの対応策ですのでご勘弁。

なんとか解決。
Pythonista への道は険しい

11
11
12

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
11