質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Q&A

解決済

1回答

2122閲覧

pythonのargparseを用いたファイル読み込みの不具合

M.Temma

総合スコア7

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

0グッド

0クリップ

投稿2016/07/30 07:16

###前提・実現したいこと
pythonでオプション("-3"や"-6")をつけて場合分けをし、さらに引数としてファイルを読み込みファイルの中身について操作を行うプログラムを作ろうとしています。
具体的に書くと、ターミナルで
$ python PracticeD-3.py test.fa
として実行すると、ファイル"test.fa"を読み込み、関数"frame1"のみを実行する
$ python PracticeD-3.py -3 test.fa
として実行すると、ファイル"test.fa"を読み込み、関数"frame1"と"frame3"を順番に実行する
$ python PracticeD-3.py -6 test.fa
として実行すると、ファイル"test.fa"を読み込み、関数"frame1"と"frame3"と"frame6"を順番に実行する
というようなプログラムを作ろうとしています。

しかし、実装すると下記のような実行となりうまくいきません。

なお、ファイル"test.fa"の中身は次の通りです。

sequence1

ccg agc aga gct ttc tgg aga gag gaa gag gaa gag gaa gtg gga ggc ggg ccc tag

###発生している問題・エラーメッセージ

オプション無しの場合は、 $ python PracticeD-3.py test.fa として実行すると、 >sequence1 ccg agc aga gct ttc tgg aga gag gaa gag gaa gag gaa gtg gga ggc ggg ccc tag frame1 と出力され問題ないのですが、 "-3"のオプションをつけて、 $ python PracticeD-3.py -3 test.fa として実行すると、 >sequence1 ccg agc aga gct ttc tgg aga gag gaa gag gaa gag gaa gtg gga ggc ggg ccc tag frame1 frame3 と出力され、関数"frame1"が実行された後、ファイルの中身がうまく読み込めないか、なくなってしまっているのです。 オプション"-6"の時も同様で、 python PracticeD-3.py -6 test.fa >sequence1 ccg agc aga gct ttc tgg aga gag gaa gag gaa gag gaa gtg gga ggc ggg ccc tag frame1 frame3 frame6 となってしまいます。 argparseの仕様がよくわかっていないことが大きいと思いますが、どうすれば $ python PracticeD-3.py -3 test.fa >sequence1 ccg agc aga gct ttc tgg aga gag gaa gag gaa gag gaa gtg gga ggc ggg ccc tag frame1 >sequence1 ccg agc aga gct ttc tgg aga gag gaa gag gaa gag gaa gtg gga ggc ggg ccc tag frame3 といったように、関数ごとにうまく実行できるでしょうか。 ご助言よろしくお願いします。

###該当のソースコード

#!/usr/bin/env python # coding: utf-8 import sys import argparse def main(): parser = argparse.ArgumentParser(description='Process options') group = parser.add_mutually_exclusive_group() group.add_argument('-3', dest='frame3', action='store_true', default=False, help='recognize -3') group.add_argument('-6', dest='frame6', action='store_true', default=False, help='recognize -6') parser.add_argument('file', type=file) args = parser.parse_args() if args.frame3: test_file1 = args.file test_file2 = args.file frame1(test_file1) frame3(test_file2) elif args.frame6: test_file1 = args.file test_file2 = args.file test_file3 = args.file frame1(test_file1) frame3(test_file2) frame6(test_file3) else: frame1(args.file) def frame1(f): for i in f: print i, print "frame1" def frame3(f): for i in f: print i print "frame3" def frame6(f): for i in f: print i print "frame6" if __name__ == "__main__": main()

###補足情報(言語/FW/ツール等のバージョンなど)
テキストエディタ:atom
実行環境:python2.7.10

なお、質問のために関数は単純なものにしてあります。
あくまで問題解決のための即席関数です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

全ての関数で同じファイルオブジェクトを参照しています。
このため、frame1(f)でファイルを読み終わった段階でそのファイルオブジェクトはファイルの終端を参照しています。
このためframe3, frame6では読むものがもうないので何も起きていないように見えます。

つまりこう書いているのと同じことが起きています。

py

1def frame1(f): 2 for i in f: 3 print i, 4 print "frame1" 5 for i in f: 6 print i 7 print "frame3"

今回で言えば各関数の先頭でファイルオブジェクトを先頭に戻せば元の位置に戻ります。

def frame1(f): f.seek(0) #これを追加 for i in f: print i, print "frame1"

frame3,frame6にも同様にf.seek(0)を入れてください。

ただし今回のプログラムでは影響は出ませんが、関数間が関係しあうプログラムだと他の関数の動作に影響がでますのでその点は注意してください。

例えば

def frame1(f): f.seek(0) print "1 :", f.readline() frame4(f) print "1 :", f.readline() def frame4(f): f.seek(0) print "4 :", f.readline()

こういう処理だった場合にはframe4の操作がframe1の操作に影響を及ぼすという意味です


余談ですが、python2系(2.7.5以降だったかな)を使うときは先頭で、3系互換のprint_functionを強制するようにしておいた方が良いでしょう。

#!/usr/bin/env python # coding: utf-8 from __future__ import print_function import sys import argparse # print "aaa" # エラーとなる print("aaa") # こっちだと print関数に関しては3系にすぐ適用できる

投稿2016/07/30 09:09

flied_onion

総合スコア2604

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

M.Temma

2016/07/31 02:57

解決しました! どうもありがとうございますm(__)m
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問