gpt4 book ai didi

python - 脚本如何用作命令行应用程序或模块

转载 作者:太空宇宙 更新时间:2023-11-03 16:52:35 26 4
gpt4 key购买 nike

我觉得这应该是显而易见的,但我已经在谷歌上搜索了很多关于这个问题的信息,但我还没有找到解决方案,所以如果您可以的话,我将不胜感激:

我编写了一个 python 脚本,我希望能够将其用作命令行应用程序,同时也可以将其用作可以在其他应用程序中加载的模块。到目前为止,我只编写了命令行选项的代码。以下是我的文件 etl.py 结构的摘要:

import os
import re
import sys
import shlex
import argparse
import itertools
import subprocess
from sqlalchemy import create_engine, text
# other imports here...

def etl(argv):
"""
ETL function for rasters ...
# more doc here
"""
args = parser.parse_args(argv)
d = vars(args)

os.chdir(d.get("root_dir"))
files = [f for f in os.listdir(".") for p in d.get("products") if p in f]

# a) Reprojection (option "r")
if d.get("which") == "r":
for f in files:
ofile = os.path.abspath(os.path.join(d.get("reproj_dir"), f))
if os.path.exists(ofile):
if d.get("overwrite") is True:
gdutil.reproject(os.path.abspath(f), ofile, .get("proj"))
else:
print("{}: File already exists. skipping".format(ofile))
else:
gdutil.reproject(os.path.abspath(f), ofile, d.get("proj"))
print("All files reprojected into EPSG {}".format(d.get("proj")))

# b) Merge (option "m")
if d.get("which") == "m":
# more operations here until...

if __name__ == '__main__':
parser = argparse.ArgumentParser(
description="""
'Extract, Transform, Load' script for rasters ...""",
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument("-dir", help="""
directory containing the input rasters to process

default value is the current directory""",
dest="root_dir", default=os.getcwd(), const=os.getcwd(), nargs="?", metavar="DIR")
gen_opts = argparse.ArgumentParser(add_help=False)
gen_opts.add_argument("-p", help="""
product type(s) to process

default is to process all products in DIR.

""".format(os.path.basename(sys.argv[0])),
dest="products", nargs="*", metavar="PROD")

# more gen_opts arguments here

subparsers = parser.add_subparsers()
parser_r = subparsers.add_parser("r", help="""
reproject rasters into target reprojection

if rasters corresponding to the passed arguments are found, they will be
reprojected into the target spatial reference system as defined by
the passed EPSG code

reprojected files will have the same pixel resolution as the input
rasters

resampling method is nearest neighbor

reprojected files are saved to the folder specified with option -r_dir
or to its default value if missing
""".format(os.path.basename(sys.argv[0])),
parents=[gen_opts, overw_opts])
parser_r.add_argument("proj", help="""
EPSG code of the destination reprojection""",
type=int, metavar="EPSG_CODE")

# more parser_r arguments here

parser_r.set_defaults(which="r")
parser_m = subparsers.add_parser("m", help="""
merge input rasters into a mosaic

rasters are merged based on the supplied level

all files that are included in a merge must have the same projection,
pixel size, no-data value, and be unique in space. otherwise, results
are not guaranteed""", parents=[gen_opts, group_opt, overw_opts])
parser_m.add_argument("-m_dir", help="""
if supplied, the merged rasters will be saved in directory M_DIR

if not supplied they will be saved to a subfolder named 'merged'
located at in DIR, or in R_DIR if a reprojection was made in the same
call""",
dest="merge_dir", type=str, nargs=1, metavar="M_DIR")
parser_m.set_defaults(which="m")

# more parsers and arguments here

# etl(sys.argv)
etl(["-dir", "E:\\Data\\Spatial\\soilgrids.org", "r", "3175", "-c", "M"])

到目前为止,我只能在最后一行未注释的情况下运行它,并从终端调用脚本而不带参数,但这不是现在的主要问题。

我的问题是:如何将该脚本用作可以在其他脚本中导入的模块,例如从 etl 导入重新项目?

我认为一件事是将我的部分代码(即以注释开头的每个部分,例如a)重新投影,b)合并,c)...)放在自己的函数中:

def reproject():
# add code here

def merge():
# add code here

然后向每个解析器添加默认函数(例如 parser_r.set_defaults(func=reproject)),但是如果我还想从另一个要导入的应用程序中使用它们,我将如何定义每个函数定义的参数模块etl,例如:

from etl import reproject
reproject() # arguments?

我必须添加可选参数或关键字吗?我是否必须测试参数是否可以使用 parser.parse_args 进行解析?我该怎么做?

非常感谢您的帮助!

最佳答案

您必须更改函数的调用签名(和正文)

def etl(argv):
...

这样它就不会对argv做任何事情。相反,它看起来像:

def etl(products, reproj_dir, ...):
...

这称为为函数定义接口(interface)

您可以将所有参数解析内容保留在 if __name__ == '__main__': block 中,但是当您调用 etl 时,您应该使用sys.argv 的内容。 您也应该将调用 parser.parse_args 的行移到此 block 内。

看看函数的主体,它似乎进入了两种模式,所以实际上最好是 def reprojectdef merge,然后确定正如您所想的那样,这些接口(interface)。

一旦有了正确的接口(interface),只需导入模块并直接调用这些函数即可。实际功能根本不需要了解命令行界面。

关于python - 脚本如何用作命令行应用程序或模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35736253/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com