機械伯爵の最新Python講座
  1. 蝶と生糸 00/12/04 01:48
  2. csv2fig.py 00/12/05 00:04
  3. JPython導入 00/12/20 15:36
  4. PEPってナニ?(1) 01/01/05 13:04
  5. PEPってナニ?(2) 01/01/06 12:53
  6. PEPってナニ?(3) 01/01/07 14:15
  7. PEPってナニ?(4) 01/01/10 23:30
蝶と生糸
00/12/04 01:48
 ・・・えと、間違い無くPythonの話題です、ええ。

 蝶→てふ→TeXとゆーのは定番なので、なんとな〜くわかるかとおもわれます
が、生糸とゆーのは「raw文字列」のことです。

※rawは生、文字列(string)はもともと「糸」の意味です。

 いや、Pythonの教科書を見ると、raw文字列とゆーのは、「正規表現を使うた
めにある」と必ず書いてあるので、私は今までほとんど使ってきませんでした
(わざわざ正規表現オブジェクト(reオブジェクト)にコンパイルするくらいなら、
Pythonなんか使わずにawkで済ませます)

 ところが、このraw文字列って、他の言語のコードを自動生成するのにけっこ
う便利なんですよね。

 特に、\(私の場合は¥ですけど)を悪夢のように乱発するTeXのコードを生
成するのに、いちいち\\でエスケープすると、もうそのコードは悪夢のように
見にくいものになります(その上、そもそも改行に\\を使うので、その見苦し
さたるや・・・悲惨なものがあります)

 そんなときに、raw文字列を使うと、非常にすっきりしたコードが書けるわけ
です。

 なお、Pythonの'',""の2種類の文字列括弧の使い分けは、HTMLコードのアラ
イメント(属性)を""で囲むのにも簡単に出来ますので、これも便利に使わせて
もらってます。

 「書ける」だけなら、Perlにでもできますが、コードに「きれいに」「見やす
く」を追求するPythonならではのこだわりがうかがえます(笑)

 ・・・まぁ、Python通の方なら「ジョーシキ」かもしれませんが、とりあえず、
Pythonってどんな言語だろうか、と探りを入れてる非Pythonユーザを意識して、
ちょっと書いてみました(笑)

  REC 2000.12.04(MONDAY) 00:56
  vzz00500@nifty.ne.jp 機械伯爵

<Python初心者/未体験者のための豆知識>
※raw文字列
 Pythonの文字列表現の一つ(Python 1.5以降)
 r'文字列'と書くことによって、文字列にたとえ\(¥)が含まれていてもそ
のままの文字列として文字列オブジェクトを生成できます。
 例えば・・・
 print r'\put(5,5){\vector(1,0){3}}'
 と書けば、そのまま・・・
 \put(5,5){\vector(1,0){3}}
 と出力されます。
 本文で書いたとおり、\(¥)を頻繁に使うTeXのコマンドを自動生成するス
クリプトがこれによって非常にすっきりと書くことができます。
 なお、通常のスクリプト、及びプログラム言語では、通常、こんな風に書く必
要があります。
 "\\put(5,5{\\vector(1,0){3}})"

※さまざまな文字列表現
 Pythonの文字列の書き方は、'(シングルクォーテーション)で文字列を囲む方
法と、"(ダブルクォーテーション)で囲む方法があります。
 文字列をシングルクォーテーションで囲んだ場合、ダブルクォーテーションは
文字列の中で自由に使うことができます。
 逆にダブルクォーテーションで囲んだ場合は、シングルクォーテーションが自
由に使えます。
 これは、例えば、下のようなHTMLタグを書くときに便利です。
 '<a href="fgalts.html">FGALTSへ</a>'
 ちなみに、これも\でエスケープする他の言語の書き方で書いてみましょう。
 "<a href=\"fgalts.html\">FGALTSへ</a>"
csv2fig.py
00/12/05 00:04
"""
--この部分はコメントなので、そのまま実行できます--
csv2fig.py ver.1.0
LaTeX2e用 CSV -> Figure Convert Script

 LaTeX2eで面倒な、Picture環境の指定をCSV(Comma Separated Value)形式で
入力するための支援スクリプトですが、まぁ、Pythonの実用例のサンプルぐら
いだと思ってください(TeXやLaTeX2eについては、適宜テキストを参照してく
ださい)
 私のように、Pythonユーザで尚且つTeXユーザという方がどのくらいいるか疑
問なのですが、とりあえず実際に試験問題を作った際に使用したものに手を加え
て作ってあります。
 Win32環境で使用した関係上、標準入出力を使用しています
(Win32環境でfile.readlines()を使うと、改行コードの関係でろくな目にあい
ません・・・)
 実行は以下のように行ってください。

python csv2fig.py << input.csv >> output.tex

 出力したコードは、そのままコンパイルして見られるように、ダミーヘッダ
とダミーフッタが入れてありますので、図を挿入する際は削除してください。
 データ書式は以下のようになります

<最初の行>
Figureの位置指定,Picture領域のx座標,Picture領域のy座標,Caption,Label

■Figureの位置指定
Figure環境の位置指定(h,t,b,pのいずれか、あるいは組み合わせ)です。
■Picture領域のx座標,y座標
Picture環境の領域のx座標とy座標ですが、単位は10pt(ポイント)であることに
注意してください。これ以降の位置や長さの単位も、基本的に全て10pt単位と
なっています。
 なぜかといえば、私自身が書いたファジーな図表には、1pt単位の指定が全く
必要でなく、全て0を余分に書いていたので、鬱陶しくてこうしました(細かい
単位が必要な方は、スクリプトを適宜改変してください)
■Caption,Label
 それぞれ、\captionと\labelに対応しています。

<データ行>
 データは、一行目以降、end.より前に書きます。
 データ行には、Vector,Line,Point,Frameboxがあります。
 データ行の第一カラムはデータの種類(v,l,p,f)を書き、第二カラムと第三
カラムは図の中の出力位置座標(開始位置)を書きます。
 座標の単位はすべて10ptです。

<Vector>
 Vector(矢印線)を出力します。フォーマットは以下のとおり。

v(vectorの識別記号),(開始点のx座標),(開始点のy座標),(傾き),(長さ)

 傾きはr(right),l(left),u(up),d(down),ru,rd,lu,ld(その組み合わせ)の8種
類が指定できます。
 また、傾きを記号で書かないでx,yの座標(-6〜6)で指定することもできますが、
その場合は第四カラムが傾きのx、第五カラムが傾きのy、第六カラムが長さと
なります。
 長さは、x座標です(傾きのxが0の場合のみy座標…詳しくはLaTeX2eの教科書参
照)

例)(20pt,30pt)の位置から右方向へ50ptのベクトル線
<CSV>
v,2,3,r,5
あるいは・・・
v,2,3,1,0,5
<TeX>
\put(20,30){\vector(1,0){50}}

<Line>
 Line(直線)を出力します。

l(lineの識別記号),(開始点のx座標),(開始点のy座標),(傾き),(長さ)

 LineはVectorと異なり方向は無いので、傾きはv(vertical縦)h(horizontal横)
s(slash/)b(backslash\)の4種類です(Vectorと同じく、xy座標で傾きを記述
できます)。
 開始点は、かならず左端です(垂直の場合は下)

例)(20pt,30pt)の位置から右上方向へ50ptの線
<CSV>
v,2,3,s,5
あるいは・・・
v,2,3,1,1,5
<TeX>
\put(20,30){\line(1,1){50}}

<Point>
 線の交差を示す黒丸(3pt)を出力します(挿入位置指定だけです)

p,x座標,y座標

例)(30pt,20pt)の位置のドット
<CSV>
p,3,2
<TeX>
\put(30,20){\circle*{3}}

<Framebox>
 指定の大きさの箱と、その中の文字を指定できます。

f,左下隅のx座標,左下隅のy座標,BOXの横幅,BOXの縦幅,挿入方向,挿入文字

 挿入文字は書かなくともかまいませんが、区切りのカンマは書いてください。
 文字は基本的に横書き専用ですが、文字を縦に配置する場合は、\\で区切っ
てください

例)(30pt,20pt)の位置の(50pt,20pt)の大きさの箱の中に「こんにちわ」
を横書きで・・・
<CSV>
f,3,2,5,2,こんにちわ
<TeX>
\put(30,20){\framebox(50,20){\shortstack{こんにちわ}}}

例)(30pt,20pt)の位置の(20pt,50pt)の大きさの箱の中に「こんにちわ」
を縦書きで・・・
<CSV>
f,3,2,2,5,こ\\ん\\に\\ち\\わ
<TeX>
\put(30,20){\framebox(20,50){\shortstack{こ\\ん\\に\\ち\\わ}}}

<データコメント>
 行頭が;のデータは、その行をスキップします。

<コメント出力>
 行頭が%の場合は、TeXドキュメントに出力するコメントを出力します。

<直接入力行>
 行頭が@の場合は、処理をスキップしてその行を直接入力します。
 行頭の@は、その際省かれます。

<終了宣言行>
end.

 この文字を検出すると、処理が中断されますので、この行以降は何を書
いてもかまいません(終了宣言行にはこの文字だけで改行してください)
 ちなみに、end.が無くても、行が終われば処理は終了します。

<空行>
 改行だけの行はスキップしますので、見やすい区切りをつけてください。
"""
# csv2fig.py ver.0.1
# CSVファイルから、LaTeX2eのpicture環境に以降するスクリプト
# python csv2fig.py << input.csv >> output.texで使用・・・

import string

# 識別子(第一カラム)
# v vector
# l line
# p point(circle*)
# c circle(未実装)
# f framebox

# <変換関数群>

# d2v:Data to Vector
# <format>
# 識別子v,put x座標,put y座標,傾きx|方向子,傾きy|省略,長さ
# \put(a1,a2){\vector(a3,a4){a5}}
# ただし、a3がr,l,u,d,ru,rd,lu,ldに限り、a4は省略可能
# 式展開は省略型に準拠させる
def d2v(data):
  i = string.split(data,',')
  if i[3] == 'r': vxy = '(1,0)'
  elif i[3] == 'l': vxy = '(-1,0)'
  elif i[3] == 'u': vxy = '(0,1)'
  elif i[3] == 'd': vxy = '(0,-1)'
  elif i[3] == 'ru': vxy = '(1,1)'
  elif i[3] == 'rd': vxy = '(1,-1)'
  elif i[3] == 'lu': vxy = '(-1,1)'
  elif i[3] == 'ld': vxy = '(-1,-1)'
  else:
    vxy='(' + i[3] + ',' + i[4] + ')'   # 傾きを作って
    i[4] = i[5]             # 省略型にあわせる
  rt = r'{\vector' + vxy + '{' + i[4] +'0}}'
  return rt

# d2l Data to line
# <format>
# 識別子v,put x座標,put y座標,傾きx|方向子,傾きy|省略,長さ
# \put(a1,a2){\line(a3,a4){a5}}
# ただし、a3がv(vertical),h(horizontal),s(slash/)b(backslash\)
# の場合はa4省略可能
def d2l(data):
  i = string.split(data,',')
  if i[3] == 'v':lxy='(0,1)'
  elif i[3] == 'h':lxy='(1,0)'
  elif i[3] == 's':lxy='(1,1)'
  elif i[3] == 'b':lxy='(1,-1)'
  else:
    lxy='(' + i[3] + ',' + i[4] + ')'   # 傾きを作って
    i[4] = i[5]             # 省略型にあわせる
  rt = r'{\line' + lxy + '{' + i[4] +'0}}'
  return rt

# d2p:Data to Point
# 引数dataは、インターフェイス統一のためのダミーなので、
# csvファイルではputの座標を指定するだけ
def d2p(data):
  return r'{\circle*{3}}'

# d2f:Data to Framebox
# Framebox format
# 識別子,put x,put y,大きさx座標(x10),大きさy座標(x10),文字
def d2f(data):
  i = string.split(data,',')
  rt = r'{\framebox('+i[3]+'0,'+i[4]+'0){\shortstack{'+i[5]+'}}}'
  return rt

print '% 画像確認用ダミーヘッダ'
print r'\documentclass{jarticle}'
print r'\begin{document}'

# Picture環境,Figure環境
# <format>
# figure position,picture x,picture y,caption,label
# x10で指定
# pel:picture environment list
pel = string.split(raw_input(),',')
print r'\begin{figure}[' + pel[0] + ']'
print r'\begin{center}'
print r'\begin{picture}(' + pel[1] + '0,' + pel[2]+'0)'
#dataOptions:インターフェイス
dataOptions={'v' : d2v,
             'l' : d2l,
             'p' : d2p,
             'f' : d2f}
while 1:
  try:
    data=raw_input()
  except EOFError:  # ファイル終末制御
    break
  else:
    if data == 'end.':  # 終了制御
      break
    elif data == '':    # 空行スキップ
      continue
    elif data[0] == ';':# データ用コメント
      continue
    elif data[0] == '%':        # TeXコメント出力
      print '% ' + data[1:]
    elif data[0] == '@':        # 直接入力
      print data[1:]
    else:
      k = string.split(data,',')
      head = r'\put(' + k[1] + '0,' + k[2] + '0)'
      foot = (dataOptions[k[0]])(data)
      print head + foot
print r'\end{picture}'
print r'\end{center}'
print r'\caption{' + pel[3] + '}'
print r'\label{' + pel[4] + '}'
print r'\end{figure}'
print '% 画像確認用ダミーフッタ'
print r'\end{document}'
'''
<権利と免責>
このスクリプトはPDSとさせていただきますので、ご自由にお使いください。
ただし、このスクリプトを利用して何らかの不利益をこうむっても、一切
責任は負いませんので、自己責任で運用してください。
・・・とはいっても、たいしたコトになる筈は無いと思いますが・・・
vzz00500@nifty.ne.jp 機械伯爵

---サンプル(切り取ってご使用ください)---
h,20,15,チャート,chart2
;サンプルテキスト
l,1,13,h,4
f,5,12,6,2,時間経過
v,11,13,r,3
v,1,11,r,13
;下のコメントは出力されますが、これは出ません
%コメント1
f,14,10,4,4,A\\B
p,5,11
l,5,9,v,2
f,4,7,2,2,ア
v,6,8,r,8
%コメント2
f,14,7,4,2,C
p,8,8
l,8,6,v,2
f,7,4,2,2,イ
v,9,5,r,5
%コメント3
f,14,4,4,2,C
p,11,5
l,11,3,v,2
;円オブジェクトを挿入する正式なLaTeX2eコマンドです
@\put(50,50){\circle{20}}
f,10,1,2,2,ウ
v,12,2,r,2
f,14,1,4,2,文字列
end.
---これ以降は、何を書いても関係ありません。---
'''
JPython導入
00/12/20 15:36
<attention>
 本発言には、Javaの知識があることを前提として書いてありますので、「なん
じゃこれわっ!」という点があれば、ご質問ください。
</attention>

 以前にJPythonのことを少し書いたのですが、実は自分で使ってた、とゆーよ
り本の受け売りが大半だったことを、ここで告白いたします(爆)

 ・・・実際は、始めるまでが大変ですわ・・・

 前にも、クロスプラットフォームが問題だとゆーことをチラッと話したかと思
いますが、それ以上に最近「PythonをインストールしていないとPythonスクリプ
トは実行できない」とゆーあたりまえの矛盾をかかえて悶々としていました。

 Pythonを広めるには、まずPythonの威力を知ってもらう必要があるのですが、
手始めにスクリプトを動かすのに「Pythonをインストールして」とゆーのは通用
しません(爆)

 これがUNIX系の実装ならFreeze(PythonプログラムをCソースにコンバートする
ツール)が使えるのですが、WinやMacにはそれも通用しない・・・(私はへーぼ
んなWinユーザです)

 とゆーわけで、とりあえずウィルスのように広く伝染しているJVM経由で
Pythonを布教すべく、JPythonをいじりだしたわけですが・・・

 まず・・・Javaは久々なのでJDKを1.3.0にばーじょんあっぷ!(少し昔はJava
者でした)

 Javaの文法を思いだしながらHello World!を書いてテスト。

public class Test{
    public static void main(String argv[]){
        System.out.println("Hello world!");
    }
}

 ・・・あ”〜めんどくさ〜

C:\>set path=%path%;c:\jdk1.3\bin
C:\>javac Test.java
C:\>java Test

 テスト終了・・・(この間、Stringをstringと書いてエラーを出したり、セミ
コロンを忘れたりして3回書きなおし・・・予想以上にブランクが影響している
模様・・・)

 さて、ダウンロードしたJPython11.classを実行・・・すると、なにやら見な
れた画面が・・・InstallShield(Java版)ですね、コレ・・・

 とゆーわけで、いくつかのファイルが展開されたのだけど・・・

 「はじめてのPython」では、jpythonをタイプすれば実行できると書いてある
のだけど、どこをどう見てもjpython.exeもjpython.comもjpython.batも無
い・・・・

 ためしにプロンプトからキーインしてみたけど・・・むだむだぁっ!

 ただし、こまったことに、javaのクラスファイルも見当たらない・・・ので、

C:\jdk1.3\jpython>java jpython

 も全く当たらず・・・・

 ・・・・jpython.jarとゆーjarファイル(Java ARchives)があるので、たぶん
コレだろうと見当をつけたのだけれども・・・

C:\jdk1.3\jpython>jar tvf jpython.jar

 で、とりあえず内容をタイプしてみると・・・スクロールしまくり・・・

C:\jdk1.3\jpython>jar tvf jpython.jar >> list.txt

 で打ち出すと、どうやらorg/python/core/にJPython.classがあるので、

C:\jdk1.3\jpython>set claspass=.;c:\jdk1.3\jpython\jpython.jar

 でクラスパスを設定し・・・

C:\jdk1.3\jpython>java jpython

 で、ようやく懐かしいPythonインタープリタが起動しました。

 現在、いろいろとテスト中ですが、まず、コンソールから直接入力したS-JIS
文字を解読不可能文字としてコンソールに吐き出すとゆー困った現象は確認して
います(どうやら、バイナリのままでなく、文字認識しようとしてバグってるら
しい・・・)

 JPythonには、JVM用のFreezeツールもあるようなので、Pythonを100%PureJava
コードに変換することも可能のようです(GUIとか使ってなければ・・・)

 これだけ苦労してJPythonを使う価値があるのかどーかは疑問ですが、まぁ、
いろいろと制約の多いJavaの代わりにPythonで気軽にコーディングできるという
メリットは、結構大きいのではないでしょうか?(Java言語も嫌いじゃないのだ
けど、ちょっとした作業にはやっぱり少し面倒臭い・・・)

 とゆーわけで、JPythonをつかってるとゆー物好きな人、他にいませんか?

  REC 2000.12.12(TUESDAY) 17:23
  vzz00500@nifty.ne.jp 機械伯爵

※蛇足
 日本での最強のライバルRubyに、とうとう256本が・・・まぁ、UNIXとゆー
「正統」があるRubyでは、Winは邪道なんだけど、もともとMacで実装され、UNIX
やWinで広まったPythonには邪道もくそもないなぁ・・・とゆーわけで、もし
「邪道編」が出るなら、たぶんJPythonだろう(爆)
・・・誰かPythonの256本書いて・・・(泣)

※※さらに蛇足・・・
*256本・・・「にひゃくごじゅうろっぽん」と読まないように・・・言うま
でも無いと思うけど、アスキーの「〜を256倍使う本」とゆーシリーズのこと
である。
PEPってナニ?(1)
01/01/05 13:04
 新世紀、あけましておめでとうございます。
 機械伯爵です。
 新世紀に合わせて、Pythonも1.5.2から2.0にバージョンアップしました。
 インストールした印象としては、tcl/tkライブラリがPythonフォルダに入れら
れてすっきりしたという程度でしょうか。
 ただ、1.6から導入されたPEPについては、目うろこでした。
 PEP(Python Enhancement Proposal)は、Pythonの文法自体の拡張で、ようする
に新しい書き方ができるようになったわけです。
 というわけで、まだ日本語版の説明の出ていない、PEPについてちょっと書き
たいと思います(TextはPythonフォルダのNEWS.txtです)

 1.代入演算子の導入
 Pythonの文法は、Cなどとちがって代入は式でなく文です。
 よって、代入子「=」は特別扱いであり、それ以外の代入子はいままでありま
せんでした。
 ところがPEPでは、

 += -= *= /= %= **= <<= >>= &= ^= |=

 の11種類の代入演算子が導入されました。
 これによって、C言語風の簡易表現が書けるようになったわけです(単項演算
子++とかは、まだありませんが)
 まぁ、フツーに使う分には確かにC言語系と同じなんですが、問題はクラスで
演算子の再定義(オーバーロード)を行った場合です。

 たとえば、Numクラスという整数のラッパクラスを作ろうとしたとしましょう。
 このNumクラスは、フィールドのvに値としての整数値を格納し、演算子をフツ
ーに使えるようにしたいと思います。
 というわけで、まずはフツーに+演算子をオーバーロードしてみましょう。

class Num:
  def __init__(self,v=0):
   self.v = v
  def __add__(self,other):
    return self.v + other
  def __radd__(self,other):
    return other + self.v

n = Num(10)

 これで、n + 5 とか5 + nとかの演算子は、フツーに整数値として使えるわけ
です。
 ところが、今回導入された+=を使うと、このままだとちとまずいことになりま
す。

 n += 5

 この演算は・・・

 n = n + 5

 に展開されるわけです。
 しかし、上の例からすれば、n + 5は組み込みのint型の答えを返してしまいま
すので、nはint型の5になり、Numクラスではなくなってしまいます。
 まぁ、__add__の定義でNum型を生成して返せば問題は無いのですが、オブジェ
クト指向と手続き型のチャンポンのPythonでは、それが時々うざったいときもあ
ります。

 というわけで、+=のフックである__iadd__メソッドは、こんなとき役に立ちま
す。
※頭にiをつけると、代入演算子のフックメソッドになります。

class Num:
  def __init__(self,v=0):
   self.v = v
  def __add__(self,other):
    return self.v + other
  def __radd__(self,other):
    return other + self.v
  def __iadd__(self,other):
    self.v += other
    return self

n = Num(10)

 self.vはint型の変数ですから、self.v += otherは、

 self.v = self.v + other

 となります。
 考えてみれば、これで操作は終了してしまうはずですから、メソッドの内容は
この一行で終わりのはずです。
 では、最後のreturn selfはなんでしょうか?

 実は、最後の行を抜かすと、n += 5の結果、nにはNoneが代入されてしまいま
す。
 つまり、最終的にnには「返り値」が「代入」されるのです。
 よってselfを返しておかないと、デフォルトの返り値であるNoneが代入されて
しまうのです。
 これで、n += 5は、見た目の通りn.vを5だけ増加する演算となります。

※ただし、この例では、n = n + 5とn += 5の結果が違ってしまうので、こうい
った実装方法がOO手法として「正しい」かどうかは疑問の余地がありますが。

 なお、余談ですが、__riadd__とゆーフックメソッドは無いよーです(いらん
わな・・・)

  REC 2001.01.05(FRIDAY) 11:38
  vzz00500@nifty.ne.jp 機械伯爵
PEPってナニ?(2)
01/01/06 12:53
というわけで、PEP(Python Enhancement Proposal)の2つめ、参りましょう。

 [x**2 for x in range(10)]

 ・・・これ、何だと思いますか?

 Smalltalkのカスケードのように、[]の中に実行文が入っていますが、やっぱ
りPythonの文ですから、[]はやっぱりリストです。

 コレ実は、リスト定義の新しい書き方なんです。

 まずは、上の例を実行してみましょう。

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

 大体見当がつくと思いますが、解説して見ましょう。

 x**2は、今までのPythonのxの二乗の書き方です。

 このxは、for x in range(10)で定義されます。

 すなわち、for <val> in <sequence>:<statement>のstatementで使用される
valについて、演算を行ってリスト化することができるわけです。

list = [x**2 for x in range(10)]

 という文を旧式のPythonの文で書いてみましょう。

list = []
for x in range(10):
  list.append(x**2)

 一般式は次のようになります。

[<expression> for <variable> in <sequence>]

 さて、これだけで終わらないのがおもしろいところです。

 実は、次のような書き方もできるんです。

list = [x for x in range(100) if x % 5 == 0]

[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 
90, 95]

 頭のx for x in range(100)の部分は、x ** 2のように、演算せずにそのまま
評価しただけですが、その後をみてください。

 x % 5 == 0は、その通り「5で割り切れる数」をしめしています。

 つまり、新しいリストに加えるメンバーについて、条件をつけることができる
ようになったわけです。

 一応、展開してみましょう。

list = []
for x in range(100):
  if x % 5 == 0:list.append(x)

 無論、最初の評価の通り、xに対して演算を行ってからリストに加えることも
可能です。

 一般式は以下の通りになります。

[<expression> for <variable> in <sequence> if <condition>]

 さて、このifやforのオプションは、ネストすることが可能です。

 テキストに出ていた例題をピックアップしてみましょう。

    def flatten(seq):
        return [x for subseq in seq for x in subseq]

    flatten([[0], [1,2,3], [4,5], [6,7,8,9], []])

This prints

    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

 入れ子となったリストを解いてフラットにする関数です(敢えて説明はしませ
んので、考えてみてください)

 新しい書き方は、ともすればPython哲学(笑)が嫌う「見苦しい書き方」になる
危険性をはらんでいますので、「コードは再利用を考えて見やすく」という大原
則を忘れずに・・・

  REC 2001.01.06(SATURDAY) 11:35
  vzz00500@nifty.ne.jp 機械伯爵
PEPってナニ?(3)
01/01/07 14:15
 PEP(Python Enhancement Proposal)の第3弾は、キーワードが増えます。

 import文に、asというキーワードが使えるようになりました。

 この使い方は、というと、いたって簡単。

 例えば、stringモジュールは非常に便利なのですが、stringという名前をモジ
ュール内で使いたい場合、ちと面倒になります。

 無論関数毎にfrom import文を使って導入しても構わないのですが、それはそ
れで面倒くさい・・・

 かといって、from string import * とやるのは、モジュール全体の名前を把
握していないと、時には危険です。

 こんなとき、Pythonの付属モジュールを見ると、こんなトリックがつかってあ
ります。

import string
s_ = string
del string

 最後のdel stringは、初めて見るとぎょっとしますが、ご安心を。

 単にモジュールからstringという名前を削除しているだけで、stringモジュー
ルには何の影響もありません。

 まず、import文でstringモジュールを名前空間に登録し、stringの名前でアク
セスできるようにします。

 次に、s_という変数にstringモジュールへの参照を割り当てます。

 最後に、stringという名前を削除します。

 削除した名前は、自由に使えます(無論delせずに上書きしても問題ありませ
ん)。

※副作用として、短い名前に割り当てることによってコーディングの手間を省く
という考えもありますが、省力化のあまり、見づらいコーディングにならないよ
う注意しなければならないのは勿論ですね・・・

 と、いうわけで、こういった動作を1文で行ってしまおうというのが、asキー
ワード導入の考えです。

 上の例にでてきた3文は、PEPにより、以下のように記述できるようになりま
した。

import string as s_

 すなわち「〜として」という形で、名前を指定してモジュールを参照できるよ
うになったのです。

 無論、fromを使った文でもつかえます。

from string import split as cutWord

 この場合、string.split()がcutWord()として使えるようになるわけです。

 文法をまとめましょう。

import <Module> as <Name>
from <Module> import <Object> as <Name>

 名前のつけかえ、というテクニックは、使い捨てのスクリプトではあまりあり
がたみのなさそうな機能ですが、モジュールが巨大化してくると、結構便利です。

 ・・・事実、クラスやモジュールを乱用する私は重宝してます、ハイ。

  REC 2001.01.07(SUNDAY) 13:39
  vzz00500@nifty.ne.jp 機械伯爵
PEPってナニ?(4)
01/01/10 23:30
 PEPシリーズの最後です。

 今回のは・・・う〜ん、便利なのはわかるんだけど、ちとコードが汚くなるか
も・・・という感じの拡張print文の'>>'です。

 今回は、最初に書式から書いてみましょう。

 print >> <file> , <string>

 で、<string>を<file>に書きこみます。

 ちなみにfileは、sys.stderrのようなものでもかまいません。

 (ちなみに、<file>をsys.stdoutやNoneとすると、従来のprint文になります)

 要するに・・・

 <file>.write( <string> )の省略書式だと考えてください。

 まぁ、シェルスクリプトに慣れてる人は、>>によるリダイレクトは見やすいの
でしょうが、私はC++のcout << XXさえ抵抗があったので、多分あまり使わない
と思います。

 ちなみに、

 print <string> >> <file>

 はエラーになります・・・(ようするに'>>'で認識してるよーです・・・うぅ
む)

 さて、4回にわたって、PEPの概説をしてきたわけですが、大切なのは第一に
「コードのわかりやすさ」第二に「コードの手間を省けること」だと思います。

 逆になると・・・多分Pythonらしくなくなるのでは?と、私は思いますが、あ
なたはいかがですか?

  REC 2001.01.10(WEDNESDAY) 23:12
  vzz00500@nifty.ne.jp 機械伯爵