Pythonistaのようなコヌド慣甚的なPythonパヌト2

Kaa、Python


短い䌑憩の埌、David Goodgerの蚘事「本物のPythonistのようにコヌドを曞くPython idiomat 」の翻蚳の最埌の郚分を玹介したす


最初ず2番目の郚分ぞのリンク。


この蚘事の著者はアメリカを発芋しおいないこずを匷調したすが、ほずんどのPythonistはアメリカに「特別な魔法」を芋぀けたせん。 しかし、Pythonでさたざたなコンストラクトを䜿甚および遞択する方法論は、読みやすさずPEP8むデオロギヌぞの近さずいう点で非垞に詳现です。
著者の蚘事のいく぀かの堎所では、゜ヌスコヌドの䟋はありたせん。 もちろん、私はそれをそのたたにしおおきたしたが、私自身は思い぀きたせんでした。原則ずしお、著者が䜕を念頭に眮いおいたかは明らかです。





リストのゞェネレヌタヌ「リスト内包衚蚘」-「リストの畳み蟌み」ずしお-泚釈。翻蚳


リストゞェネレヌタヌ略しお「listcomps」は、次のパタヌンの構文ショヌトカットです。
forおよびifステヌトメントを䜿甚した埓来の方法
new_list = []<br/>
for item in a_list:<br/>
if condition(item):<br/>
new_list . append(fn(item))<br/>

リストゞェネレヌタヌの堎合
new_list = [fn(item) for item in a_list<br/>
if condition(item)]<br/>

リストゞェネレヌタヌは明確で簡朔です。 リストゞェネレヌタヌでは倚くのネストされたfor条件ずif条件が必芁になる堎合がありたすが、2぀、3぀のルヌプ、たたはif条件のセットには、ネストされたforルヌプを䜿甚するこずをお勧めしたす。 Python Zenによるず、より読みやすい方法を遞択するこずをお勧めしたす。
たずえば、0〜9の数字シリヌズの正方圢のリスト
>>> [n ** 2 for n in range ( 10 )]<br/>
[ 0, 1 , 4 , 9 , 16 , 25 , 36 , 49 , 64 , 81 ]<br/>

0〜9の奇数の正方圢のリスト
>>> [n ** 2 for n in range ( 10 ) if n % 2 ]<br/>
[ 1 , 9 , 25 , 49 , 81 ]<br/>



ゞェネレヌタ匏1


数倀の二乗を合蚈しお100にしたしょう。
ルヌプ内
total = 0
for num in range ( 1 , 101 ):<br/>
total += num * num <br/>

sum関数を䜿甚しお、適切なシヌケンスをすばやく組み立おるこずができたす。
リストゞェネレヌタヌの堎合
total = sum ([num * num for num in range ( 1 , 101 )])<br/>

ゞェネレヌタヌ匏の堎合
total = sum (num * num for num in xrange( 1 , 101 ))<br/>

ゞェネレヌタ匏「genexps」はリストゞェネレヌタず同じくらい簡単ですが、リストゞェネレヌタは「貪欲」であり、ゞェネレヌタ匏は「遅延」です。 リストゞェネレヌタヌは、結果リスト党䜓を䞀床に蚈算したす。 匏ゞェネレヌタヌは、必芁に応じお、パスごずに1぀の倀のみを蚈算したす。 これは、蚈算されたリストが最終結果ではなく、単なる䞭間ステップである長いシヌケンスで特に圹立ちたす。
この堎合、関心があるのは合蚈金額のみです。 䞭間の2乗リストは必芁ありたせん。 同じ理由でxrangeを䜿甚したす反埩ごずに倀を遅延しお返したす。

ゞェネレヌタ匏2


たずえば、数十億の数の二乗を芁玄するず、メモリ䞍足に陥り、匏ゞェネレヌタにはそのような問題はありたせん。 しかし、これにも関わらず、時間がかかりたす
total = sum (num * num<br/>
for num in xrange( 1 , 1000000000 ))<br/>

構文の違いは、リストゞェネレヌタヌは角かっこで囲たれおいたすが、ゞェネレヌタヌ匏はそうではないこずです。 ゞェネレヌタ匏は、括匧で囲む必芁がある堎合があるため、垞に䜿甚する必芁がありたす。
基本的なルヌル


これは最近仕事で出䌚った䟋です。
 䜕らかの理由で、サンプルコヌドがありたせん-箄transl。
将来の契玄のために、数字文字列ず敎数の䞡方ず月コヌドを含む蟞曞が必芁です。 1行のコヌドで取埗できたす。
 䜕らかの理由で、サンプルコヌドがありたせん-箄transl。
以䞋は私たちを助けるでしょう


最近の䟋
month_codes = dict ((fn(i + 1 ), code)<br/>
for i, code in enumerate ( 'FGHJKMNQUVXZ' )<br/>
for fn in ( int , str ))<br/>

month_codesの結果
{ 1 : 'F' , 2 : 'G' , 3 : 'H' , 4 : 'J' , ... <br/>
'1' : 'F' , '2' : 'G' , '3' : 'H' , '4' : 'J' , ... }<br/>


仕分け


Pythonでのリストの䞊べ替えは簡単です。
a_list . sort()<br/>

リストの゜ヌトはそれ自䜓で行われるこずに泚意しおください。元のリストは゜ヌトされ、゜ヌトメ゜ッドはリストたたはそのコピヌを返したせん 
しかし、䞊べ替える必芁があるが、暙準ずは異なる順序でデヌタのリストがある堎合぀たり、最初の列で䞊べ替えおから、2番目の列で䞊べ替えるなどはどうでしょうか。 最初に2番目の列、次に4番目の列で゜ヌトする必芁がある堎合がありたす。

特別な機胜を備えた組み蟌み゜ヌトリストメ゜ッドを䜿甚できたす。
def custom_cmp (item1, item2):<br/>
return cmp ((item1[ 1 ], item1[ 3 ]),<br/>
(item2[ 1 ], item2[ 3 ]))<br/>
<br/>
a_list . sort(custom_cmp)<br/>

これは機胜したすが、リストが倧きいず非垞に遅くなりたす。

DSUで䞊べ替え*


DSU =デコレヌト-゜ヌト-アンデコレヌト
*泚倚くの堎合、DSUはそれほど必芁ではありたせん。 別の方法の説明に぀いおは、次のセクション「キヌによる䞊べ替え」を参照しおください。
特別な比范関数を䜜成する代わりに、通垞の゜ヌトを行う補助リストを䜜成したす。
# Decorate: <br/>
to_sort = [(item[ 1 ], item[ 3 ], item)<br/>
for item in a_list]<br/>
<br/>
# Sort: <br/>
to_sort . sort()<br/>
<br/>
# Undecorate: <br/>
a_list = [item[ - 1 ] for item in to_sort]<br/>

最初の行は、タプルを含むリストを䜜成したす。タプルは、目的の順序の゜ヌト条件ず完党なデヌタレコヌド芁玠で構成されたす。
2行目は、埓来の゜ヌトを高速か぀効率的に実行したす。
3行目は、゜ヌトされたリストから最埌の倀を取埗したす。
この最埌の倀は、デヌタの芁玠党䜓レコヌド、ブロックであるこずに泚意しおください。 䜜業が行われた゜ヌト条件は砎棄され、それらはもはや必芁ありたせん。

これにより、䜿甚されるメモリ、アルゎリズムの耇雑さ、およびランタむムの劥協点が達成されたす。 はるかに簡単で高速ですが、元のリストを耇補する必芁がありたす。

キヌ゜ヌト


Python 2.4では、゜ヌトリストメ゜ッドにオプションの「キヌ」匕数が導入されたした。この匕数は、各リスト項目の比范キヌを蚈算するために䜿甚される単䞀の匕数の関数を蚭定したす。 䟋
def my_key (item):<br/>
return (item[ 1 ], item[ 3 ])<br/>
<br/>
to_sort . sort(key = my_key)<br/>

my_key関数は、to_sortリスト項目ごずに1回呌び出されたす。
必芁に応じお、独自のキヌ関数を収集するか、1぀の匕数の既存の関数を䜿甚できたす。


発電機


匏ゞェネレヌタヌはすでに芋たした。 任意の耇雑なゞェネレヌタヌを関数ずしお開発できたす。
def my_range_generator (stop):<br/>
value = 0 <br/>
while value < stop:<br/>
yield value<br/>
value += 1 <br/>
<br/>
for i in my_range_generator( 10 ):<br/>
do_something(i)<br/>

yieldキヌワヌドは、関数をゞェネレヌタヌに倉えたす。 ゞェネレヌタヌ関数を呌び出すず、コヌドを実行する代わりに、Pythonはゞェネレヌタヌオブゞェクトを返したす。これは、思い出すずむテレヌタヌです。 圌には次の方法がありたす。 forルヌプは、StopIteration䟋倖がスロヌされるたで次の反埩子メ゜ッドを呌び出すだけです。 䞊蚘のように、StopIterationを明瀺的たたは暗黙的に呌び出しお、コヌドの最埌で抜けるこずができたす。
特定のリストをコンパむルする必芁がないため、ゞェネレヌタヌはシヌケンス/むテレヌタヌ凊理を単玔化できたす。 反埩ごずに蚈算される倀は1぀だけです。

forルヌプが実際にどのように機胜するかを説明したす。 Pythonはinキヌワヌドの埌のシヌケンスを調べたす。 リスト、タプル、蟞曞、セット、ナヌザヌ定矩などの単玔なコンテナの堎合、Pythonはそれをむテレヌタに倉換したす。 このオブゞェクトが既に反埩子である堎合、Pythonはそれを盎接䜿甚したす。
次に、Pythonは次の反埩子メ゜ッドを繰り返し呌び出し、戻り倀をルヌプカりンタヌこの堎合はiにバむンドし、ルヌプ本䜓コヌドを実行したす。 このプロセスは、StopIteration䟋倖がスロヌされるか、ルヌプの本䜓でbreakステヌトメントが実行されるたで繰り返し繰り返されたす。
forルヌプにはelse句を含めるこずができたすそれ以倖の堎合。そのコヌドは、ルヌプの終了埌に実行されたすが、breakステヌトメントの実行埌には実行されたせん 。 この機胜は非垞に゚レガントな゜リュヌションを提䟛したす。 else節は、forルヌプで垞に䜿甚されるずは限らず、頻繁に䜿甚されるわけではありたせんが、圹に立぀堎合がありたす。 堎合によっおは、必芁なロゞックをうたく衚珟できたす。
たずえば、ある芁玠に含たれる条件を確認する必芁がある堎合、シヌケンスの芁玠は次のようになりたす。
for item in sequence:<br/>
if condition(item):<br/>
break <br/>
else :<br/>
raise Exception ( 'Condition not satisfied.' )<br/>



ゞェネレヌタヌの䟋


CSVファむルたたはリストのアむテムから空の行を陀倖したす。
def filter_rows (row_iterator):<br/>
for row in row_iterator:<br/>
if row:<br/>
yield row<br/>
<br/>
data_file = open (path, 'rb' )<br/>
irows = filter_rows(csv . reader(data_file))<br/>


テキストファむルから行を読み取る


datafile = open ( 'datafile' )<br/>
for line in datafile:<br/>
do_something(line)<br/>

他のむテレヌタが行うように、ファむルは次のメ゜ッドをサポヌトするため、これは可胜ですリスト、タプル、蟞曞キヌ甚、
ゞェネレヌタヌ。
ここで泚意しおくださいファむル操䜜のバッファリングのため、Python 2.5+を䜿甚しおいない堎合、.nextメ゜ッドず.read *メ゜ッドを混圚させるこずはできたせん。


EAFP察 LBYL


蚱可よりも蚱しを求める方が簡単です。 蚱可よりも蚱しを求める方が簡単です
7回枬定し、1぀切りたす。 跳躍する前に芋おください
EAFPが通垞奜たれたすが、垞にではありたせん。


EAFP try /䟋を陀いお


䟋倖を起こしやすいコヌドをtry / exceptブロックに入れお゚ラヌをキャッチするず、すべおのオプションを提䟛しようずした堎合よりも䞀般的な解決策になる可胜性がありたす。
try :<br/>
return str (x)<br/>
except TypeError :<br/>
... <br/>

泚キャッチする必芁のある䟋倖を垞に特定する必芁がありたす。 玔粋なexcept節を䜿甚しないでください。 玔粋な䟋倖条件は、コヌドで発生するすべおの䟋倖をキャッチし、デバッグを非垞に困難にしたす。

むンポヌト


from module import * <br/>

モゞュヌルむンポヌト匏でこの「ワむルドカヌド」ワむルドカヌド、テンプレヌトを芋たこずがあるでしょう。 おそらくあなたも圌女が奜きです。 䜿甚しないでください。
有名な察話の適応
倖偎のダゎバ、ゞャングル、沌地、霧。
ハッチモゞュヌルのむンポヌトから*明瀺的なむンポヌトよりも優れおいたすか
䟝田良くないです。 より速く、より簡単に、より魅惑的に。
ルヌクしかし、明瀺的なむンポヌトの方がワむルドカヌドよりも優れおいるこずをどうやっお知るのですか
䟝田半幎埌に詊しおコヌドを読みたいずきを芋぀けたす。

念のため、元のテキストを匕甚したす-泚。翻蚳。
ダゎバの倖装、ゞャングル、沌地、ミスト。
LUKEモゞュヌルからのむンポヌトは、明瀺的なむンポヌトよりも優れおいたすか
䟝田いいえ、良くありたせん。 より速く、より簡単に、より魅惑的に。
LUKEしかし、なぜ明瀺的なむンポヌトの方が優れおいるのかをどのようにしお知るこずができたすか
ワむルドカヌド圢匏
䟝田コヌドを6か月間読もうずするずき
今から。

ワむルドカヌドのむンポヌト-Pythonのダヌクサむド。

絶察に
モゞュヌルのむンポヌトから*名前空間をひどく汚染したす。 ロヌカルネヌムスペヌスに、受信する予定のないオブゞェクトがありたす。 モゞュヌルで以前に定矩されたロヌカルの名前をオヌバヌラむドする名前を確認できたす。 これらの名前の由来を正確に把握するこずはできたせん。 この圢匏は短くシンプルですが、最終的なコヌドには属しおいたせん。
道埳 ワむルドカヌドでむンポヌトを䜿甚しないでください
はるかに良い

名前空間汚染アラヌム
代わりに、
モゞュヌルを介しお名前をバむンドしたす詳现を説明する識別子、起源を瀺したす
import module <br/>
module . name<br/>

たたは、゚むリアスを䜿甚しお長いモゞュヌル名をむンポヌトしたす。
import long_module_name as mod <br/>
mod . name<br/>

たたは、必芁な名前のみを明瀺的にむンポヌトしたす。
from module import name<br/>
name<br/>

このフォヌムは、モゞュヌルの線集ず再読み蟌み "reload"が必芁な察話型むンタヌプリタヌでの䜿甚には適しおいたせん。

モゞュヌルずスクリプト


むンポヌトされたモゞュヌルず実行可胜スクリプトの䞡方を䜜成するには
if __name__ == '__main__' :<br/>
# script code here <br/>

むンポヌトするず、__ name__モゞュヌル属性が拡匵子「.py」なしのファむル名ずしお蚭定されたす。 したがっお、モゞュヌルがむンポヌトされるず、if条件の䞋のコヌドは機胜したせん。 スクリプトを実行するず、__ name__属性が "__main__"に蚭定され、スクリプトコヌドが機胜したす。
いく぀かの特別な堎合を陀き、すべおのコヌドを最䞊䜍に眮くべきではありたせん。 関数、クラス、メ゜ッドのコヌドを非衚瀺にし、__ name__ == '__main__'の堎合はコヌドを閉じたす。


モゞュヌル構造


"""module docstring""" <br/>
<br/>
# imports <br/>
# constants <br/>
# exception classes <br/>
# interface functions <br/>
# classes <br/>
# internal functions & classes <br/>
<br/>
def main ( ... ):<br/>
... <br/>
<br/>
if __name__ == '__main__' :<br/>
status = main()<br/>
sys . exit(status)<br/>

これがモゞュヌルの構造です。

コマンドラむン凊理


䟋cmdline.py
#!/usr/bin/env python <br/>
<br/>
"""<br/>
Module docstring.<br/>
"""
<br/>
<br/>
import sys <br/>
import optparse <br/>
<br/>
def process_command_line (argv):<br/>
"""<br/>
Return a 2-tuple: (settings object, args list).<br/>
`argv` is a list of arguments, or `None` for ``sys.argv[1:]``.<br/>
"""
<br/>
if argv is None :<br/>
argv = sys . argv[ 1 :]<br/>
<br/>
# initialize the parser object: <br/>
parser = optparse . OptionParser(<br/>
formatter = optparse . TitledHelpFormatter(width = 78 ),<br/>
add_help_option = None )<br/>
<br/>
# define options here: <br/>
parser . add_option( # customized description; put --help last <br/>
'-h' , '--help' , action = 'help' ,<br/>
help = 'Show this help message and exit.' )<br/>
<br/>
settings, args = parser . parse_args(argv)<br/>
<br/>
# check number of arguments, verify values, etc.: <br/>
if args:<br/>
parser . error( 'program takes no command-line arguments; ' <br/>
'"%s" ignored.' % (args,))<br/>
<br/>
# further process settings & args if necessary <br/>
<br/>
return settings, args<br/>
<br/>
def main (argv = None ):<br/>
settings, args = process_command_line(argv)<br/>
# application code here, like: <br/>
# run(settings, args) <br/>
return 0 # success <br/>
<br/>
if __name__ == '__main__' :<br/>
status = main()<br/>
sys . exit(status)<br/>



パッケヌゞ


package / <br/>
__init__ . py<br/>
module1 . py<br/>
subpackage / <br/>
__init__ . py<br/>
module2 . py<br/>


䟋
import package.module1 <br/>
from package.subpackage import module2<br/>
from package.subpackage.module2 import name<br/>

Python 2.5では、将来のむンポヌトを通じお絶察および盞察むンポヌトが可胜になりたした。
from __future__ import absolute_import<br/>

ただ十分に理解できおいないので、この郚分の説明は省略したす。


単玔なものは耇雑なものよりも優れおいる


たず、デバッグはコヌドを曞くよりも2倍難しくなりたす。 したがっお、可胜な限りスマヌトにコヌドを蚘述した堎合、定矩䞊、デバッグするのに十分なほどスマヌトではありたせん。
—ブラむアンW.カヌニハン、 Cプログラミング蚀語ず「AWK」の「K」の共著者

蚀い換えれば、プログラムをシンプルにしおください

車茪を再発明しないでください


コヌドを曞く前に


参照資料









この蚘事はHabra Editorで䜜成され、コヌドサンプルはデフォルトスタむルのHabra-colorerでペむントされおいたす。

Source: https://habr.com/ru/post/J90493/


All Articles