我喜欢argparse
模块。 argparse.FileType
也很有用,除非您希望默认值不是sys.std*
,因为即使您提供了默认输出文件,也会创建默认输出文件
值。
例如:
parser.add_argument('--outfile', type=FileType('w'), default="out.txt")
即使您使用--outfile指定文件,也会创建out.txt。
我能想到的最好的是:
class MagicFileType(object):
def __init__(self, *args, **kwargs):
# save args/kwargs and set filetype to None
self.filetype = None
self.args = args
self.kwargs = kwargs
def __getattr__(self, attr):
""" Delegate everything to the filetype """
# If we haven't created it, now is the time to do so
if self.filetype is None:
self.filetype = FileType(*self.args, **self.kwargs)
self.filetype = self.filetype(self.filename)
return getattr(self.filetype, attr)
def __call__(self, filename):
""" Just cache the filename """
# This is called when the default is created
# Just cache the filename for now.
self.filename = filename
return self
但如果觉得这样比较容易,我会错过什么吗?
答案 0 :(得分:3)
argparse
,http://bugs.python.org/issue12776(2012年8月)进行了相对较新的更改,延迟了对默认值的评估。最初,字符串默认值将在解析开始时通过type
(通过_get_value
)传递,从而导致打开(和创建)FileType文件(无论是否需要)。在此修补程序中,字符串将写入命名空间,但在解析结束之前不会计算,此时它可以确定是否提供了其他值。基本上,此行已从parse_known_args
的早期移至_parse_known_args
default = self._get_value(action, action.default)
在http://bugs.python.org/issue13824中,我提出了一个提供FileContext
类型的补丁。它与FileType
的主要区别在于它将open(file...)
包裹在partial
中。这样,在实际用于with args.output() as f:
上下文之前,不会打开(或创建)文件。
该修补程序处理其他一些事情,例如测试是否可以创建文件(使用os.access
)并在虚拟上下文中包装stdin/out
,以便它不会尝试关闭它。
如果不进行测试,您可以像这样修改FileType
:
class FileOpener(argparse.FileType):
# delayed FileType;
# sample use:
# with args.input.open() as f: f.read()
def __call__(self, string):
# optionally test string
self.filename = string
return self
def open(self):
return super(FileOpener,self).__call__(self.filename)
file = property(open, None, None, 'open file property')