如何将参数传递给 Python 模块中的主函数?
Posted
技术标签:
【中文标题】如何将参数传递给 Python 模块中的主函数?【英文标题】:How to pass arguments to main function within Python module? 【发布时间】:2017-08-02 12:21:40 【问题描述】:我最近开始了解有关 Python 包和模块的更多信息。我目前正忙于更新我现有的模块,以便可以作为脚本运行或作为模块导入到我的其他代码中。我不确定如何在模块中构造输入参数并将它们传递给模块中的 main() 函数。
我已经编写了我的 main() 函数并在 if __name__ == '__main__' 下调用它并传递输入参数。输入当前是硬编码的,以显示我想要实现的目标。对于如何正确构造用户将传递的输入参数,然后将其传递给主函数的任何帮助,我们将不胜感激。
如上所述,当直接使用或作为模块导入我的其他代码并从那里运行时,我试图能够将以下内容用作脚本。如果我将它作为模块导入,我会在导入时调用 main() 函数吗?以下结构在我编写以下内容时是否正确?任何建议表示赞赏。
'''
Created on March 12, 2017
Create a new ArcHydro Schema
File Geodatabase and Rasters
Folder
@author: PeterW
'''
# import site-packages and modules
import re
from pathlib import Path
import arcpy
# set environment settings
arcpy.env.overwriteOutput = True
def archydro_rasters_folder(workspace):
"""Create rasters folder directory
if it doens't already exist"""
model_name = Path(workspace).name
layers_name = re.sub(r"\D+", "Layers", model_name)
layers_folder = Path(workspace, layers_name)
if layers_folder.exists():
arcpy.AddMessage("Rasters folder: 0 exists".format(layers_name))
else:
layers_folder.mkdir(parents=True)
arcpy.AddMessage("Rasters folder 0 created".format(layers_name))
def archydro_fgdb_schema(workspace, schema, dem):
"""Create file geodatabase using XML
schema and set coordinate system based
on input DEM if it doesn't already exist"""
model_name = Path(workspace).name
fgdb = "0.gdb".format(model_name)
if arcpy.Exists(str(Path(workspace, fgdb))):
arcpy.AddMessage("0 file geodatabase exists".format(fgdb))
else:
new_fgdb = arcpy.CreateFileGDB_management(str(workspace), fgdb)
import_type = "SCHEMA_ONLY"
config_keyword = "DEFAULTS"
arcpy.AddMessage("New 0 file geodatabase created".format(fgdb))
arcpy.ImportXMLWorkspaceDocument_management(new_fgdb, schema,
import_type,
config_keyword)
arcpy.AddMessage("ArcHydro schema imported")
projection = arcpy.Describe(dem).spatialReference
projection_name = projection.PCSName
feature_dataset = Path(workspace, fgdb, "Layers")
arcpy.DefineProjection_management(str(feature_dataset),
projection)
arcpy.AddMessage("Changed projection to 0".format(projection_name))
def main(workspace, dem, schema):
"""main function to create rasters folder
and file geodatabase"""
archydro_rasters_folder(workspace)
archydro_fgdb_schema(schema, dem, workspace)
if __name__ == '__main__':
main(workspace = r"E:\Projects\2016\01_Bertrand_Small_Projects\G113268\ArcHydro\Model04",
dem = r"E:\Projects\2016\01_Bertrand_Small_Projects\G113268\ArcHydro\DEM2\raw",
schema = r"E:\Python\Masters\Schema\ESRI_UC12\ModelBuilder\Schema\Model01.xml")
更新日期:13 年 3 月 17 日
以下是我根据乔纳森的建议更新的 Python 模块:
'''
Created on March 12, 2017
Create a new ArcHydro Schema
File Geodatabase and Rasters
Folder
@author: PeterW
'''
# import site-packages and modules
import re
from pathlib import Path
import arcpy
import argparse
# set environment settings
arcpy.env.overwriteOutput = True
def rasters_directory(workspace):
"""Create rasters folder directory
if it doens't already exist"""
model_name = Path(workspace).name
layers_name = re.sub(r"\D+", "Layers", model_name)
layers_folder = Path(workspace, layers_name)
if layers_folder.exists():
arcpy.AddMessage("Rasters folder: 0 exists".format(layers_name))
else:
layers_folder.mkdir(parents=True)
arcpy.AddMessage("Rasters folder 0 created".format(layers_name))
def fgdb_schema(workspace, schema, dem):
"""Create file geodatabase using XML
schema and set coordinate system based
on input DEM if it doesn't already exist"""
model_name = Path(workspace).name
fgdb = "0.gdb".format(model_name)
if arcpy.Exists(str(Path(workspace, fgdb))):
arcpy.AddMessage("0 file geodatabase exists".format(fgdb))
else:
new_fgdb = arcpy.CreateFileGDB_management(str(workspace), fgdb)
import_type = "SCHEMA_ONLY"
config_keyword = "DEFAULTS"
arcpy.AddMessage("New 0 file geodatabase created".format(fgdb))
arcpy.ImportXMLWorkspaceDocument_management(new_fgdb, schema,
import_type,
config_keyword)
arcpy.AddMessage("ArcHydro schema imported")
projection = arcpy.Describe(dem).spatialReference
projection_name = projection.PCSName
feature_dataset = Path(workspace, fgdb, "Layers")
arcpy.DefineProjection_management(str(feature_dataset),
projection)
arcpy.AddMessage("Changed projection to 0".format(projection_name))
def model_schema(workspace, schema, dem):
"""Create model schema: rasters folder
and file geodatabase"""
rasters_directory(workspace)
fgdb_schema(schema, dem, workspace)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Create a ArcHydro schema')
parser.add_argument('--workspace', metavar='path', required=True,
help='the path to workspace')
parser.add_argument('--schema', metavar='path', required=True,
help='path to schema')
parser.add_argument('--dem', metavar='path', required=True,
help='path to dem')
args = parser.parse_args()
model_schema(workspace=args.workspace, schema=args.schema, dem=args.dem)
【问题讨论】:
【参考方案1】:这对我来说是正确的,是的,如果您希望将其用作模块,则可以导入 main.不过,以更具描述性的方式命名它可能会更好。
阐明__main__
和函数main()
的工作原理。当您执行一个模块时,它将有一个存储在__name__
中的名称。如果您将模块作为脚本单独执行,它将具有名称__main__
。如果您将它作为模块的一部分执行,即将它导入另一个模块,它将具有模块的名称。
函数main()
可以任意命名,这不会影响您的程序。它通常在小脚本中命名为main
,但如果它是较大代码体的一部分,它就不是一个特别好的名字。
就让用户在作为脚本运行时输入参数而言,我会考虑使用argparse
或click
argparse 如何工作的示例。
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(description='Create a ArcHydro schema')
parser.add_argument('--workspace', metavar='path', required=True,
help='the path to workspace')
parser.add_argument('--schema', metavar='path', required=True,
help='path to schema')
parser.add_argument('--dem', metavar='path', required=True,
help='path to dem')
args = parser.parse_args()
main(workspace=args.workspace, schema=args.schema, dem=args.dem)
【讨论】:
您好乔纳森,感谢以下内容。所以我的 main() 函数不必叫 main? 不,你可以随意称呼它。我更新了答案以包含更多细节:) 嗨乔纳森,你能给我一个例子,如何使用 argparse 将参数传递给我的 main() 函数。询问的原因是我在 main() 函数中调用了两个使用参数工作区的函数。 我已经更新了答案,包括如何使用 argparse。 嗨乔纳森,我非常感谢你,你帮了大忙。以下内容将极大地帮助我推进我的代码。以上是关于如何将参数传递给 Python 模块中的主函数?的主要内容,如果未能解决你的问题,请参考以下文章
使用 argparse 将参数发送到 Python 脚本中的函数