假设我有一个简单的 Python 脚本do_stuff.py
,它列出给定文件夹中的子文件夹:
import click
@click.command(help="Do stuff.")
@click.argument('datasets', type=click.Path(exists=True, readable=True, writable=True), nargs=-1)
def main(datasets):
for dataset in datasets:
print(dataset)
if __name__ == "__main__":
main()
就我而言,它在我运行时返回预期的文件夹列表python3 do_stuff.py ./s3_data/lsc2/landsat_ot_c2_l2/*
:
./s3_data/lsc2/landsat_ot_c2_l2/LC08_L2SP_195027_20220121
./s3_data/lsc2/landsat_ot_c2_l2/LC08_L2SP_195027_20220206
./s3_data/lsc2/landsat_ot_c2_l2/LC08_L2SP_195027_20220222
./s3_data/lsc2/landsat_ot_c2_l2/LC08_L2SP_195027_20220310
当我尝试从另一个脚本做同样的事情时master.py
,导入do_stuff.py
:
from do_stuff import main as ds
ds('./s3_data/lsc2/landsat_ot_c2_l2/*')
当我运行python3 master.py
它返回:
Usage: master.py [OPTIONS] [DATASETS]...
Try 'master.py --help' for help.
Error: Invalid value for '[DATASETS]...': Path '/' is not writable.
如果我修改master.py
into的最后一行ds(['./s3_data/lsc2/landsat_ot_c2_l2/*'])
,那么我得到:
Usage: master.py [OPTIONS] [DATASETS]...
Try 'master.py --help' for help.
Error: Invalid value for '[DATASETS]...': Path './s3_data/lsc2/landsat_ot_c2_l2/*' does not exist.
提前感谢您提供的任何帮助。
为了让您充分理解看起来不同的行为,您将其误认为“一旦导入后点击路径类型行为不同”,我建议您进行以下实验。在您的do_stuff.py
中,检查click
从命令行'./s3_data/lsc2/landsat_ot_c2_l2/*'
传递时实际收到的参数。这可以通过在之前添加这几行来完成main()
if __name__ == "__main__":
import sys
print(sys.argv)
main()
现在运行它:
$ python do_stuff.py ./s3_data/lsc2/landsat_ot_c2_l2/*
['do_stuff.py', './s3_data/lsc2/landsat_ot_c2_l2/LC08_L2SP_195027_20220121', './s3_data/lsc2/landsat_ot_c2_l2/LC08_L2SP_195027_20220206', './s3_data/lsc2/landsat_ot_c2_l2/LC08_L2SP_195027_20220222', './s3_data/lsc2/landsat_ot_c2_l2/LC08_L2SP_195027_20220310']
./s3_data/lsc2/landsat_ot_c2_l2/LC08_L2SP_195027_20220121
./s3_data/lsc2/landsat_ot_c2_l2/LC08_L2SP_195027_20220206
./s3_data/lsc2/landsat_ot_c2_l2/LC08_L2SP_195027_20220222
./s3_data/lsc2/landsat_ot_c2_l2/LC08_L2SP_195027_20220310
请注意它实际上是您拥有的四个文件的列表,并且在*
程序中无处可见。这是因为在 shell 中,它会在命令实际运行之前自动扩展通配符,因此 Python(因此click
)只会看到完全限定的文件名,并且循环会愉快地运行。
从命令行模拟失败的一种简单方法(不必set glob
按照上一段中的链接线程进行处理)以重复您从调用中看到的失败,ds('./s3_data/lsc2/landsat_ot_c2_l2/*')
是传入带有通配符的路径,该通配符将无法解决到任何文件,例如:
$ python do_stuff.py /tmp/a_dir_does_not_exist/*
Usage: do_stuff.py [OPTIONS] [DATASETS]...
Try 'do_stuff.py --help' for help.
Error: Invalid value for '[DATASETS]...': Path '/tmp/a_dir_does_not_exist/*' does not exist.
由于 shell 无法扩展该通配符参数,因此其未修改的形式将作为参数传递给程序,并且在示例中,它ds(['/tmp/a_dir_does_not_exist/*'])
根据问题中的失败示例模拟调用。
现在,如果您想在 Python 中使用相同的 glob 语法,您可以使用该glob.glob
函数在 shell 中复制自动通配符扩展,例如:
>>> from do_stuff import main as ds
>>> from glob import glob
>>> ds(glob('./s3_data/lsc2/landsat_ot_c2_l2/*'))
./s3_data/lsc2/landsat_ot_c2_l2/LC08_L2SP_195027_20220310
./s3_data/lsc2/landsat_ot_c2_l2/LC08_L2SP_195027_20220222
./s3_data/lsc2/landsat_ot_c2_l2/LC08_L2SP_195027_20220206
./s3_data/lsc2/landsat_ot_c2_l2/LC08_L2SP_195027_20220121
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句