2016-10-25 3 views
0

私はLinux監査を解析するプログラムを作成しており、システムコール名と番号の間にマップを作成する必要があります。システムコールは/usr/include/asm/unistd_64.hから来て、次の形式を取る:リストの理解は、次のコードを読みやすくしますか?

#define __NR_read 0 
#define __NR_write 1 
#define __NR_open 2 
#define __NR_close 3 

次のコードは動作します:

SYSCALLS = {} 
SYSCALL_HEADERS="/usr/include/asm/unistd_64.h" 

with open(SYSCALL_HEADERS) as syscalls: 
    for line in syscalls: 
     if "_NR_" in line: 
      sysc, syscn = re.split('_NR_| ', line.strip())[2:] 
      SYSCALLS[syscn] = sysc 

をしかし、少し長い息切れようです。リストの理解度を使ってコードを短縮して読みやすくする方法はありますか?

+0

私は、これは意見のより問題だと思い...私見長く複雑なリスト内包は、コードを作ります読みにくく、コードを他の人が読んでいる場合は注意深く使用してください。私は個人的には、コードとその意図について少し教えてくれる変数の助けを借りているのが好きです... – BorrajaX

+0

それは超有効なポイントです。フィードバックをお寄せいただきありがとうございます! – Shibby

答えて

3

あなたは同じ出力を生成するためにdictの内包表記を使用することができます。

with open(SYSCALL_HEADERS) as syscalls: 
    SYSCALLS = { 
     syscn: sysc 
     for line in syscalls if "_NR_" in line 
     for sysc, syscn in (re.split('_NR_| ', line.strip())[2:],)} 

を、私はそれはもはや読み取り可能であることとは思いません。

+0

あなたは+1を得ます。正解ではありませんが正しいですが、それ以上は読めないというコメントがあります。 – sberry

-1

はこれを試してみてください:

f = open("/usr/include/asm/unistd_64.h")  
SYSCALLS = {k:v for line in f.readlines() 
      for k,v in (re.split('_NR_| ', line.strip())[2:],) 
      if "_NR_" in line} 
+0

ファイル全体をただちに反復することができるときに、ファイル全体をリストに読み込む必要はありません。 –

+0

@MartijnPietersあなたは正しいです。ありがとう;) – MMF

+1

また、間違った場所でフィルタリングします。行内の '_NR_ 'は重要です。なぜなら' re.split() 'が空行に適用されないようにするからです。 –

0

短く、必ずしも必要ではないが、より読み:

>>> dict(l.split("_")[3:][0].split(" ")[::-1] for l in f if "_NR_" in l) 
{'1': 'write', '3': 'close', '0': 'read', '2': 'open'} 
+0

@MartijnPieters修正済みですが、それがさらに悪化しています。 – L3viathan

+0

ええ、私は 'dict(genexp) 'も考えましたが、その理由のためにそれを捨てました。 –

関連する問題