トップページ⇒tech
1001コメント298KB

Pythonのお勉強 Part6

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさんNGNG
日本Pythonユーザ会
http://www.python.jp/Zope/
Python オフィシャルサイト
http://www.python.org/

前スレ
http://pc5.2ch.net/test/read.cgi/tech/1095684242/
06856812005/06/18(土) 02:19:11
Windowsあたりから来た場合タブ幅が4だったりするので、スペースとタブを混在させると原因が理解できないバグを発現させる可能性があるからじゃないでしょーか。
UNIXから来た場合はタブ幅が8なので、問題なかったりするのですが。
0686デフォルトの名無しさん2005/06/18(土) 05:09:52
>>681
実際に使用するライブラリがあればそっちのライセンスを適用すべきだけど、
参考までに、apr-util(Apache Portable Runtime utility)のmd5 encodeでは、
アルゴリズムはFreeBSDのcryptから借りてきたよ。とだけコメントに書かれてます。
緩いライセンスなので、それほど気にする必要はなかったかな。改変も商用利用も問題ないです。

>>684
PEP8 Style Guide for Python Codeですね。
April oneのは、構文解析時にスタイルを強制するかも、って話で、
そこに書かれてる作法自体は、PEP8スタイルガイドで昔から推奨されてます。
0687デフォルトの名無しさん2005/06/18(土) 06:20:30
他の言語でも公開するようなソースはtab>whitespace変換しとけみたいなこと言われてないか?
0688デフォルトの名無しさん2005/06/18(土) 15:39:26
>685
おいおい
viでもset tabstop=4とかすりゃ……
0689デフォルトの名無しさん2005/06/19(日) 00:54:25
組み込み言語としてのPythonってどうですか?
現在WindowsXP + VC++.NET + DirectX + Python2.4で、ゲームを作っています。
ネイティブコードより、Pythonを呼び出してPythonからネイティブコードをCallできる
仕組みを利用しているのですが、Pythonモジュールの呼び出しのオーバヘッドや動作速度が気になります。
06906892005/06/19(日) 00:56:13
質問age
0691デフォルトの名無しさん2005/06/19(日) 02:58:10
>>689
質問は具体的に。
0692デフォルトの名無しさん2005/06/19(日) 10:02:51
組み込みって言われると機器の制御とかそういう方を思い浮かべた俺
06936892005/06/19(日) 13:46:11
>>691
組み込み用途としてPythonを採用しているソフトって、メタセコイアぐらいしか知らないんで
他にどういった使われ方をされているか知りたい。
0694デフォルトの名無しさん2005/06/19(日) 14:08:25
>>693
メタセコよりBlenderの方が色々な使い方をしてるな。
ソースも公開されてるし。
一応、PS2・PCゲーなどで組み込まれた実績あり。
検索すれば出てくる。

ただ、組み込み系はメモリ的にキツいだろうね。
メモリが足りない=ストップだから。
0695デフォルトの名無しさん2005/06/19(日) 14:12:18
>>693
その方面だと Shade、trueSpace、Blender あたりが有名かな。
いずれも Python による scripting が可能だそーだ。
06966892005/06/19(日) 14:24:55
>>694
結構採用実績がありますね…。PS2で組み込まれたのはすごいな。
BlenderもPythonだったのかぁ、知らなかった。使いにくくて辞めたけど…。
気になったのは、メモリの関連。Pythonってメモリ使用量多いですか…?
すごく気になる。

>>695
trueSpaceみたいなゲームフレームワークも採用しているのか。
自分が思いついた事はもう既に誰かが実践しているのね。ちょっと悲しい。
Shadeは使っているんだけど、Pythonスクリプティング可能だったのかー!
知らなかったー…。
0697デフォルトの名無しさん2005/06/19(日) 14:45:57
10年以上の歴史がある言語だからねえ。
06986892005/06/19(日) 14:47:26
>>694
Pythonドキュメントで10.1 Allocating Objects on the Heapの項である
関数以外でPythonがヒープに大きく影響する?
PyMethod_Functionを呼んだ先でヒープ確保とかしているということ?
Pythonのメモリマネジメントってどうなっているのか分からない…。
0699デフォルトの名無しさん2005/06/19(日) 14:52:03
>>697
10 年は若い方

>>698
前に調べた時は GC は参照カウント + ループ回避だったみたい
07006892005/06/19(日) 14:58:16
>>699
CからPythonの関数を呼んだ時に、Pythonが確保するヒープ容量って
どのように制御されているか分かりますか?
Pythonが勝手にメモリを食っていくようだと、かなり厳しいのですけど…。
できれば呼び出し側のC側で使用メモリ容量を制限したいんですが。
0701デフォルトの名無しさん2005/06/19(日) 19:57:07
>>696
> 気になったのは、メモリの関連。Pythonってメモリ使用量多いですか…?

組み込み用途として考えると多い、と言えるだろうね。Pythonに限らず
RubyもLuaも基本的な作りは同じだと思うよ。便利モジュールをインポート
して使用メモリの増加を見るといい。

基本的に処理の呼び出しが名前ベースで解決されるから、
インスタンスが増えれば増えるほどその分文字列のデータが
増えてくわけだ。名前で解決するからこそ便利な一面も
あるわけだけど。
適当にしか見てないからウソ言ってるかも。

自分アプリに組み込むか、ソースをコンパイルするなりして、
デバッガでmallocしているところを追うのが手っ取り早い。
マニュアル見れば結構簡単にできる。

スクリプティング可能にして、ユーザに拡張させることを考えると
どれだけのメモリを使うか予想が付かないから組み込みでは
キツい、という自分なりの結論。後、Pythonは基本的に保護
機能みたいなのが無いから、行儀の悪いことされると困る。
性善説に基づいているような言語って感じ。
0702デフォルトの名無しさん2005/06/19(日) 20:55:23
そんなタイトな環境でスクリプトを使う神経がわからんダスよ
0703デフォルトの名無しさん2005/06/19(日) 22:47:41
>>698
> Pythonのメモリマネジメントってどうなっているのか分からない…。
つpython/dist/src/Python/memmove.c
07046892005/06/19(日) 23:08:47
>>701
Python側で変なコード書かないかチェックしなきゃいけないって事ですね・・・。
参考になりました。もうちっと追っていきます。
(自分はPy_InitModule呼んだ段階でヒープは全て確保済みだと思っていた・・・)

>>702
ゲームとかゲームとかゲームとか・・・

>>703
眺めておきます(ぉ
0705デフォルトの名無しさん2005/06/19(日) 23:25:52
Poser3DにもPythonスクリプト載っている
0706デフォルトの名無しさん2005/06/19(日) 23:36:13
>>704
> ゲームとかゲームとかゲームとか・・・

だったらBlenderが一番の参考資料になるかもね。
Pythonでゲーム向けのAPIが用意されてるよ。
色々なデモがあったはず。


個人的な考えだけど、まずはデバッグ環境用としてのみPythonを組み込んでおいて、
実行時にオブジェクトのステータスを変えたり、振る舞いを変えたり、といった
作業効率を向上させるための道具として使う。で、メモリ、動作速度面での
目処が立てば次のプロジェクトで実用へ、って感じかな。

まぁ、ゲームに組み込みを考えるならLuaの方がコンパクトだから
そっちの方が無難かも。
07076892005/06/19(日) 23:49:06
>>705,706
イロイロ参考になります(汗
今はゲームで画面遷移、パラメータ設定、セーブの為のシリアライズのみ使ってます。
Blenderソースは知らなかった・・・。探してみますね。

Luaはコンパクトな反面、標準モジュールがPythonに劣るので・・・。
時流に乗ってPythonでいきます。
0708デフォルトの名無しさん2005/06/20(月) 02:44:38
> CからPythonの関数を呼んだ時に、Pythonが確保するヒープ容量って
自分でPythonの処理系をコンパイルするなら、オプションで上限を設定できます。

> 基本的に処理の呼び出しが名前ベースで解決されるから、
> インスタンスが増えれば増えるほどその分文字列のデータが
> 増えてくわけだ。

Pythonの文字列は(関数呼出の際の関数名など内部で使われる文字列も)
重複する文字はinternとして扱われるので、メモリの面では単純に比例して増えるわけではありません。

あと、Pythonのソースで気をつける事。# とりあえず思いついただけなので、突っ込み・追加歓迎

- 事前処理以外にevalを使わない。
- (stacklessでなければ、)再帰呼出やデータの循環構造
- リストを固定長で扱う。リサイズ時に拡張されるので、appendを直接使わない。
初期化時に長さだけ確保しておく方が良い。Cの配列ようにまとまった領域が取られる為。
- クラスで抽象データ構造を表現せずに、list,dictを使い、長さ、要素の長さを制限する事で
実行時に使うデータ領域が大体予測可能になるはず。

> Luaはコンパクトな反面、標準モジュールがPythonに劣るので・・・。
組み込み向けでは、調査しなければならないライブラリが増えるというデメリットもありますね。

>>703
memmove.cってメモリマネージメントとは関係ないですよ。
アロケーターとかは、src/Objects/obmalloc.c
07097012005/06/21(火) 00:26:34
>>708
詳しい情報をありが�d。

自分の中でPython組み込みのモチベーションが
下がってたからいい刺激になったよ。
07106892005/06/21(火) 01:26:22
まじ皆さん情報感謝しています。

>>708
組み込み向けPython Scriptingも奥が深い…。気をつけることが満載ですね。
>自分でPythonの処理系をコンパイルするなら、オプションで上限を設定できます。
自分も該当コードを見つけて喜んでいました。

>組み込み向けでは、調査しなければならないライブラリが増えるというデメリットもありますね。
Python使う理由が、C/C++のライブラリ探すの面倒くさいというのもあったりしてなかなか難しいです…。
通信関係は全てPythonに依存しています…。
0711デフォルトの名無しさん2005/06/21(火) 01:54:42
draft を Python で実装(ほとんど設計と同義)して
そして徐々に C++ → C → asm で*変換*していくストラテジーは
組み込み系*でも*有用だと思いますよ。
ブランチコード全体に於ける Python コード行のパーセンテージの表示で
進捗状況をアナウンスするとおもろいかもね。
07126482005/06/22(水) 00:07:16
とりあえずモジュール書きに挑戦してみますた。パスワードファイルとグループファイルをいじくるためのモジュールです。
http://iwa.ath.cx/software/python/ApacheAuthFile.tar.bz2
python歴10日足らずなので、命名規則等も含めて「よりpythonらしい」書き方の添削キボンヌ。
ファイルの更新がatomicでないので、壊れたファイルをApacheに読まれる可能性がありますが、一時ファイル作ってリネームというのをやり始めてみたら、排他制御が面倒だったので……(^^;
0713デフォルトの名無しさん2005/06/22(水) 10:15:19
>>710 追加で、
- appendの他にも配列型のオブジェクト全般で(文字列、タプル、リスト, ...)の 連結・反復 + * += *= や スライス。
- リストの場合、可能なら遅延リスト(GeneratorやIterator)で表現するとメモリを節約になる。

通信だと、marshalを通信プロトコルでオブジェクトのシリアライズに使わないとか。
組み込みに限った話ではありませんが、セキュリティ面での注意も幾つかありますね。
メモリに関していえば、数バイトの不正なデータで大量のメモリを占領されたりする等、問題になります。

ところで、ライブラリ込での組み込みとなると、ライブラリがすでに富豪的に書かれてるので、
これらの省メモリ・テクニックってあまり効果がないかも知れないなぁ。予め余裕をもってヒープ確保する方が有効だと思う。
0714デフォルトの名無しさん2005/06/22(水) 10:18:52
>>712
実行はしてないけど、見た感じだけレビュー

Pythonでのmain関数。(rubyでいう if $0 == __FILE__)
http://www.artima.com/weblogs/viewpost.jsp?thread=4829

def main(*argv):
nbsp;nbsp;# do something
nbsp;nbsp;return 0
def __name__ == '__main__':
nbsp;nbsp;sys.exit(main(*sys.argv))
モジュールの末尾に書いておくと、単体で呼ばれた時のみmainを実行される。
モジュールとして他のファイルからimportされた時にはmainは呼ばれない。

to_str -> __str__ str(obj) で __str__ が呼ばれる。
printなどで表示する時の為にも、__repr__ も実装しておくと良い。
rubyのinspect相当,オブジェクトのシリアライズにも使われるが、printデバッグ時にも使える。

set, type, int, str, list, dict, tuple, file, object などはビルトイン型の名前と重なるので、避けた方がいい。

TABとSpaceの混在 -> _match メソッド内
python -t や -tt オプション付きで実行すると確認できます。

import * でインポートする関数/クラスは __all__ で指定できるので、
モジュール内で使うローカルクラスの名前のprefixは、はずすこともできる。
0715648=7122005/06/22(水) 13:35:42
>>714
> 見た感じだけレビュー
どっちかと言うとその方面での突っ込みを期待していたので、感謝です。
> main
pythonではこう書くんですね。今回のものは、テストコードを分離したいのでこのまま行くと思いますが。
> str
obj.str()ではなくて、str(obj)なんですね。んー、rubyに毒されてるせいかもしれないけど、いまいち気に入らない……。
> ビルトイン型の名前と重なる
ライブラリリファレンス等を見てると、これって結構注意しないといけなさそう。(fileとlistはやってました^^;)
> TAB
使わないのが推奨? 気付いてなかったんですが、Emacsのpython-modeは全部スペースに展開してますね。
> __all__
どっちを使うかは好みでしょうか。ローカルスコープのものに"_"を付けるのもそれはそれでわかり易いように思うし。
# こーゆー部分で選択肢をあたえるのはびみょーにpythonらしくないよーな気するのは偏見?(^^;
0716デフォルトの名無しさん2005/06/23(木) 14:07:39
おまいらラベル高いな
0717デフォルトの名無しさん2005/06/23(木) 15:53:54
ぼくのラベルも上昇しそうです!(><)
0718デフォルトの名無しさん2005/06/23(木) 17:27:39
なんで
obj.str()
obj.len()
とかじゃなくて
str(obj)
len(obj)
なの?
0719デフォルトの名無しさん2005/06/23(木) 17:32:19
そのほうが覚えづらくて難易度が上がって上級者だから
0720デフォルトの名無しさん2005/06/23(木) 17:57:41
>>718
おかげでしょっちゅう間違えるよorz
あとperlのjoin()相当が、array.join(separator)じゃなくて、separator.join(array)だったのに愕然とした。
0721デフォルトの名無しさん2005/06/23(木) 18:48:21
PythonはSmalltalkではないし、Perlでもない
0722デフォルトの名無しさん2005/06/23(木) 18:53:07
Pythonしか使わない俺は勝ち組。
0723デフォルトの名無しさん2005/06/23(木) 19:04:58
違うのはわかるけど、直観に反してると感じられて何か気持ちよくない。
pythonという言語仕様自体は(もうperlには戻りたくないなと思う程度には)悪くないと思うんだけど、組み込み関数/クラスのデザインについてはちと、いや、かなり納得がいかない部分が……。
0724デフォルトの名無しさん2005/06/23(木) 19:10:55
もう一個。せっかくlambdaがあるのに実行文を許さないのは納得いかーん!!
無名関数/メソッドにしたいのにいちいち名前付けにゃならんのはウザいぞー。
0725デフォルトの名無しさん2005/06/23(木) 21:07:40
年食ってだんだんこだわりが無くなってきた希ガス。
動けばいいやー、みたいな。
0726デフォルトの名無しさん2005/06/23(木) 21:18:04
俺も>>723に同意
使い始めの頃 x.dir(), x.len(), x.str() て書いて怒られてたし
今も x.dir() のほうがいいと思ってる.

"".join(array) はキモイから
str.join("", array) にしてる.

あと sort() もリストを直で変える点が気に入らない.
新しいリスト作って欲しい.これは
def sort(L): L2 = L[:] ; L2.sort() ; return L2
1回書いとけば問題なし.
0727デフォルトの名無しさん2005/06/23(木) 21:20:25
str(obj)はstringのconstructorだから不自然ではあるまい。
len(obj)はlen()の実装がオブジェクト中立だから。
__len__のかわりにlen()を定義すればよい、という意見はあるだろうが、
あらゆるclassに引き継がれる大元の基底クラスで、いたずらに公開属性は定義しないというポリシーの意義は
それはそれで理解できるのではないか。
たとえばRubyはObject classにメソッドを定義しすぎで、見通しを悪くしている。
(トップレベルでユーザが定義したメソッドまで放り込まれてしまうのはもはや笑うしかない)
0728デフォルトの名無しさん2005/06/23(木) 22:27:14
なるほど
07297232005/06/23(木) 23:56:04
>>727
ふむ、そういうポリシーなわけですか。組み込み関数群を眺めてると、オブジェクトに対する基本的な操作については頑なにobject.method()になるのを避けてるよーに見えたのですが、それなら理解できなくもないです。
個人的にはruby的アプローチの方が使い勝手が良さそうには感じますけど、このあたりは個人の感性の問題かなぁ。ルートクラスがfatだと美しくないのは確かだし。
もっとも、このあたりの議論なんて、本家ではとっくに決着がついてて今さらな話のよーな気がひしひしと。
0730デフォルトの名無しさん2005/06/24(金) 00:01:47
>>726
2.4からは組み込み関数 sorted() が実装されたよ。
これは新しいリストを返してくれる。
iterableクラスのメソッドじゃないから、キモイって言われそうだけど。
0731デフォルトの名無しさん2005/06/24(金) 09:39:49
http://www.python.org/doc/faq/general.html#why-does-python-use-methods-for-some-functionality-e-g-list-index-but-functions-for-other-e-g-len-list
> The major reason is history.
(snip)
> One can quibble about individual cases but it's a part of Python,
> and it's too late to make such fundamental changes now. The functions
> have to remain to avoid massive code breakage.
0732デフォルトの名無しさん2005/06/24(金) 11:17:18
要するに「今さら変えられねーYO!」でつか(^^; 3.0にするときにでも大胆に見直ししてくんねーかな。やりすぎるとperl6になってしまうけど(ぉ
0733デフォルトの名無しさん2005/06/24(金) 16:26:06
文字列で、evalを使わずに関数やメソッドを呼び出すのってどうやるんですか?
一応、オンラインのリファレンスマニュアルやライブラリマニュアルを眺めてるんですが、どこからたぐればよいのかさっぱり……。

def func1(): ...

func = "func1"
# eval(func + "()")相当をevalを使わず実現したい

class Class1:
def method1(self): ...

obj = Class1()
method = "method1"
# eval("obj." + method + "()")相当をevalを使わず実現したい
0734デフォルトの名無しさん2005/06/24(金) 16:43:07
オブジェクトでもモジュールでも、getattrで属性を得る。
m1 = getattr(obj, "method1")
m1()

mymodule = sys.modules['__main__'] (これはもっと簡単に書けるかも)
f1 = getattr(mymodule, "func1")
f1()
0735デフォルトの名無しさん2005/06/24(金) 18:07:26
>>734
感謝!! モジュール内の関数だとsys.modules[__name__]になるのかな。……これでいけるよーだ。(もっと簡単な方法もありそーな気も)
ところで、moduleオブジェクトとか関数オブジェクトとか、処理系自身が持つクラスやオブジェクトに関して体系的に解説した本とかオンラインドキュメントってあります?
0736デフォルトの名無しさん2005/06/24(金) 21:31:35
つかぬことをお伺いしますがPythonにはconstというか定数という概念は無いのですか?
0737デフォルトの名無しさん2005/06/24(金) 22:11:41
ないない。
07387362005/06/24(金) 22:21:57
(´・ω・`) 定数ぐらい欲しいよね…
0739デフォルトの名無しさん2005/06/24(金) 22:47:08
定数は俺たちの心の中にある。
0740デフォルトの名無しさん2005/06/24(金) 22:53:31
つpi
0741デフォルトの名無しさん2005/06/25(土) 00:50:44
定数はいくらでもあるよ!!
1 <- 定数
2 <- これも定数
0742デフォルトの名無しさん2005/06/25(土) 01:29:57
いまはNoneも定数だよな?
0743デフォルトの名無しさん2005/06/25(土) 02:52:39
まあ、トラップすることはできるけど。
ttp://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/414140
0744デフォルトの名無しさん2005/06/25(土) 09:54:33
Pythonにないのは定数だけじゃない。属性の可視性の制御もない。
Pythonの世界ではプログラマはみんな仲間であり同士。
0745デフォルトの名無しさん2005/06/25(土) 11:04:49
Pythonではテメエのナニをどこにでも突っ込める。倫理違反もへったくれもない。
Pythonの世界ではプログラマはみんなケダモノであり穴兄弟。

ナンチャッテ
0746デフォルトの名無しさん2005/06/25(土) 11:18:16
モンティパイソン精神!
0747デフォルトの名無しさん2005/06/25(土) 11:29:01
プログラマさまが過ちを犯すわけがない!

Zap! Zap! Zap!
07487362005/06/25(土) 14:15:20
>>743
お、これ応用すればconst風にできるね。
ありがとう。
0749デフォルトの名無しさん2005/06/25(土) 15:02:24
それ、どんなときに使うの?
0750デフォルトの名無しさん2005/06/25(土) 20:05:16
今スト!今スト!
0751デフォルトの名無しさん2005/06/25(土) 20:12:48
>>715 > __all__
標準モジュールでもどちらにするか統率が取れていない様なので、好みの問題でしょうね。
この場合は、test_スクリプト側でモジュールをimportする際に、
名前を指定してimportする。と指摘すべきでした。でも、どちらか片方を選択と言わず、両方併用しても問題なしです。
import * する場合は、名前空間汚染の心配があるので __all__ の定義を推奨します。(個人的に)

>>735
func1がスコープ内(func1()で呼び出せる場所)にあるなら、locals()["func1"]()

>>736
> ところで、moduleオブジェクトとか関数オブジェクトとか、
> 処理系自身が持つクラスやオブジェクトに関して体系的に解説した本とかオンラインドキュメントってあります?

>>> import new
>>> help(new.module)
>>> help(new.function)
処理系の内部的な事だとC/APIドキュメント、ソースコード。
書き掛けですが、http://rupy.rubyforge.org/wiki/wiki.pl 辺りの内容に興味あります?

>>749
大袈裟な例を挙げると、True, False = False, True みたいな事が原因でプログラムが破綻するケースで、
プログラムの動作を保証する為に用いる。const(この場合は、read-only variable)で未然に防げるbugもあります。
# constの役割は、コンパイル時評価/最適化等、他にもあるけど

> const
実行時チェックは、インタプリタだとパフォーマンスに影響する事もあるので,
ソースコードの静的チェックするのは、どうでしょ?
evalやcompile,execを使わない保守的なコードを書いていれば、ある程度チェック出来るはず、
0752デフォルトの名無しさん2005/06/25(土) 20:34:55
...てことで、試しに書いてみた。> ソースの静的チェックによる検出
全然テストしてないけど、叩き台に どぉぞ。

import re, sys, token, tokenize
reConstName = re.compile('^[A-Z][A-Za-z0-9_]+$')
isConstName = reConstName.match

def check_const(filename, defined=[]):
    name = None
    for tok in tokenize.generate_tokens(open(filename).readline):
        if tok[0] == token.NAME and isConstName(tok[1]):
            name = tok[1]
        if tok[0] == token.OP and tok[1] == '=' and name and isConstName(name):
            if name in defined:
                print "%s at line %d: constant '%s' already defined." % (filename, tok[2][0], name)
            else:
                defined.append(name)
            name = None
    return defined

if __name__ == '__main__':
    defined = []
    for filename in sys.argv[1:]:
        check_const(filename, defined)
07537362005/06/25(土) 23:12:04
>>751-752
そうか、静的チェックと言う方法もありますね。
工夫でカバーできるもんだなぁ。どうもです。
0754デフォルトの名無しさん2005/06/26(日) 23:36:54
Python 難しいな
0755デフォルトの名無しさん2005/06/27(月) 10:15:08
定数として用意した属性を誤って書き替えちゃうケースって想像しにくいが。
書き替える時は意図的なんだから、書換えられないようにするのはまずくないか。

C++のような、コンパイル時にエラーがチェックできる世界が望みなら、
わざわざ動的型言語を使わんでも、と思う。
0756デフォルトの名無しさん2005/06/27(月) 12:19:24
>>751
> 書き掛けですが、http://rupy.rubyforge.org/wiki/wiki.pl 辺りの内容に興味あります?
うーん、読むだけなら(^^; Perl, Ruby, Pythonのそれぞれで、こっちの場合はこう書く、という情報には興味があります。(件のページはRubyとPythonがターゲットですが)
0757デフォルトの名無しさん2005/06/27(月) 14:59:48
>>755
うっかりミスを防ぐって意味では有効だよ。

変更されないことを前提としてコーディングしたのに、そのことを忘れて書き換えたりとかね。
0758デフォルトの名無しさん2005/06/27(月) 16:03:55
a, b, c = str.split(':')
で、要素が足りないときには足りないやつにNoneを、多いときには単に残りを無視したいのですが、何か簡潔な書き方はないですか?
0759デフォルトの名無しさん2005/06/27(月) 16:11:01
簡潔とは言い難いが
a,b,c=(str.split(":") + [None] * 3)[:3]
0760デフォルトの名無しさん2005/06/27(月) 17:01:27
左辺の内容が右辺では知りようがないから、
どうしても要素数を明示する必要があるよね。
そういうgeneratorでラップしたらいくらか格好はましになるけど、
unpackがもうちょい融通の利くものになってくれるといいよなぁ。
0761デフォルトの名無しさん2005/06/27(月) 17:50:32
> 要素が足りないときには足りないやつにNoneを、
> 多いときには単に残りを無視したい

その要求を逐語訳して if 文で書くのがいいんじゃないか?
>>759のようなコードを書くと後で読み返したとき意図不明になる希ガス。
0762デフォルトの名無しさん2005/06/27(月) 18:26:33
>>759
感謝。やっぱり、配列にn個足して前からn個切り出すしかないんですねぇ。
>>761
最初はそう書き直そうと考えたんですが、「Heavyweight Languageじゃあるまいし、こんなんいちいち書いてられっかー!!」と思わず切れたのどした。
なので、759をほぼそのまま採用する私(^^;
0763デフォルトの名無しさん2005/06/27(月) 18:51:47
これだから重い言語のほうが読みやすいんだよ
0764デフォルトの名無しさん2005/06/27(月) 18:58:13
せめて関数にするか
def fitseq(seq, n):
 return (seq + [None] * n)[:n]

たぶん同ネタがPython Cookbookにあると思うんで、誰か探してくれ。
0765デフォルトの名無しさん2005/06/27(月) 19:30:51
>>759
strが空文字列だと a="", b=c=None になるけどいいのかな?
07667582005/06/27(月) 19:47:46
>>765
空文字列も文字列だし、他の言語でも同じ結果になるはずなので、問題ないです。
……ということは、split()の結果に追加する配列は[None] * (n - 1)の方がいいのかな。
0767デフォルトの名無しさん2005/06/27(月) 20:06:36
右辺の個数が不定なのに a, b, c = ... と書くのは何か違う希ガス。
abuse というか何というか。
0768デフォルトの名無しさん2005/06/27(月) 20:11:21
1対1対応にこだわらない、きさくな代入演算子があるといいのだが
07697582005/06/27(月) 20:46:57
>>767
たーげっとは、各行が
USER_ID:ENCRYPTED_PASSWORD
もしくは
USER_ID:ENCRYPTED_PASSWORD:COMMENT
となってるファイルなんです。(要はApacheのpasswdファイル。ちなみに後者のフォーマットでもOKなのはApache2のソースで確認済み)
COMMENTが無ければNoneになってほしいわけで……。
0770オレ ◆oReSiGNpIo 2005/06/27(月) 20:49:04
>>768
そういう変なワガママを叶えるのがPerlです。
許されてないのがPythonです。たぶん。

たぶん、オレなら>>758のような問題はiteratorあたりかなぁ。
yield3回してStopIterationとか。
多少コードの量が犠牲になるけど、
読むときそれなりにわかりやすいからイインデネーノ。
0771デフォルトの名無しさん2005/06/27(月) 21:29:06
>>769
俺だったら素直に条件分けするところだなあ。

fields = line.split(":")
if len(fields) == 3:
 username, password, comment = fields
elif len(fields) == 2:
 username, password = fields
 comment = None
else:
 raise ValueError, "illegal input"
0772オレ ◆oReSiGNpIo 2005/06/27(月) 21:48:05
extend使うとすれば、こんなのでもいいかも。
4つ以上のときはシカトされるから気をつけてねw

tokens = line.split(':')
while len(tokens) < 3:
 tokens.extend([None])
0773オレ ◆oReSiGNpIo 2005/06/27(月) 21:53:36
ごめ、アゲちゃいました。
ついでに、extendでなくて、単純に
tokens.append(None)でいいんだった。
0774c2005/06/27(月) 22:40:47
from itertools import chain, islice, repeat

tokens = line.split(':')
username, password, comment = islice(chain(tokens, repeat(None)), 3)
07757582005/06/27(月) 23:06:18
>>774
う゛、読めない、マニュアル、マニュアル……えーっと、>>759をイテレータで書き直した、と考えればいーんでしょーか。
こちらの方が速度/メモリ効率は良さそうな感じ。(大した差ではないだろうけど)

でも可読性を考えると>>771が正論のよーな気がしないではない(^^;
0776オレ ◆oReSiGNpIo 2005/06/27(月) 23:14:12
キタキタ、itertoolsはまだ使ってないや。

つ http://www.python.jp/doc/release/lib/itertools-functions.html
07777582005/06/27(月) 23:21:18
chat状態だな(^^;
えーっと、repeat(None)で[None, None, ...]の無限列を生成、
chain(tokens, repeat(None))でtokens + [None, None, ...]、
islice(..., 3)で[:3]、
でもこいつらはイテレータなので実体は作らない、でOK?
0778オレ ◆oReSiGNpIo 2005/06/27(月) 23:23:27
う、先こされたけどオレも爆撃しちゃうぞ、と。

repeat(None)
こいつはNoneを延々と返すイテレータ
無限のNoneリストとでも考えてくれ

chain(tokens, repeat(None))
chainはそのまま、つなげるって意味で、
例えばchain([1,2,3], [4,5], repeat(None)) だと
1,2,3,4,5,None,None...(ずっとNone) が返る。
つまり、ここは、tokensの値を順番にかえしてから、
Noneをひたすら返す。

islice(chain(tokens, repeat(None)), 3)
単純に最初の3つを返す。感覚的にはlistobj[:3]。

>>772みたいに値がかわっちゃうのを嫌うときとかにも使えるしなかなか便利そう。
リストの機能じゃ不満な人はぜひ修得すべしってところだのう。
0779デフォルトの名無しさん2005/06/27(月) 23:50:25
[re.split('[:\n]', line)[:4] for line in file('.htpasswd')]
0780デフォルトの名無しさん2005/06/27(月) 23:56:42
for u, p, c in (re.findall('\w+', line)+[None])[:3] for line in file('.htpasswd')):
0781デフォルトの名無しさん2005/06/28(火) 11:33:54
iteratorとかgeneratorとか、こういうのをさらっと使えると何かかっこいいなあ。
0782デフォルトの名無しさん2005/06/29(水) 18:40:37
>>753 Consts
大文字とアンダースコアのみの変数を、定数としてコンパイルするスクリプト書いてみました。
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/435694

>>756
言語の比較の部分ではなくて、
Pythonの内部的な所に興味があると思ったのだけど、違ったかな...
0783デフォルトの名無しさん2005/06/29(水) 21:47:25
あっさり書くのか。
07847562005/06/29(水) 23:42:47
>>782
基本的には使う側の人なので、内部そのものよりは、
その応用編に興味があるというか。
例えば、文字列から関数やメソッドのオブジェクトをひっぱってきて
間接的に呼び出す場合だと、シンボルテーブルや関数オブジェクトの知識が
いるわけですが、そういった処理系自身のクラスやオブジェクトがどのように
関連しあっているか、というのがリファレンスマニュアルを見るだけでは
よくわからんのです。
で、そのあたりの解説が欲しいな、と。
他言語との比較については、まぁ、今までperlどっぷりだったので、
perlではこー書くんだけど、pythonではどー書くの?というのが頻発してて、
しかもそーゆー部分に限って上記のような微妙な部分だったりするので、
そういうのがまとまっていればなぁ、と。
perlでは「&{"func"}(@args)」と書くんだけど
pythonでは「locals()["func"](*args)」と書く、
ということはリファレンス見てるだけではたどり着けませんでした。
教えてもらってからあらためて読むと、なるほど、となるんですけど……。
■ このスレッドは過去ログ倉庫に格納されています