2017-03-12 4 views
3

저는 최근에 파이썬 패키지와 모듈에 대해 더 배우기 시작했습니다. 현재 스크립트로 실행하거나 다른 코드로 모듈로 가져올 수 있도록 기존 모듈을 업데이트하는 중입니다. 내 모듈 내에서 내 입력 인수를 구성하고 내 모듈 내 main() 함수에 전달하는 방법을 잘 모르겠습니다. 나는했습니다파이썬 모듈 내에서 주요 함수에 인수를 전달하는 방법은 무엇입니까?

내 내 주() 기능을 작성하고 __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") 

업데이트 : 17/03/13

다음 조나단의 제안에 따라 내 업데이트 파이썬 모듈은 다음과 같습니다

''' 
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) 

답변

5

이 나를 위해 올바른 보이는, 그래 당신이 찾고 있다면 이것을 모듈로 사용하려면 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) 
+0

안녕하세요, Jonathan, 다음에 대해 감사드립니다. 그래서 내 main() 함수를 메인이라고 부르지 않아도 되는가? –

+0

아니요, 원하는대로 부를 수 있습니다. 나는 좀 더 자세한 내용을 포함하도록 답변을 업데이트했습니다 :) – Jonathan

+0

안녕하세요 조나단, 내 main() funciton에 argparse를 사용하여 인수를 전달하는 방법에 대한 예제를 나에게 줄 수 있습니까? 묻는 이유는 인수 workspace를 사용하는 main() 함수 내에서 두 개의 함수를 호출하기 때문입니다. –