Если инструменты-скрипты запускаются в одном приложении, то вы можете контролировать работу прогрессора. Вы можете настроить вешний вид прогрессора, выбирая индикатор выполнения процесса по умолчанию или пошаговый.
Более подробно о прогрессоре см. Основы работы с прогрессором в инструментах-скриптах
Указанный ниже код демонстрирует возможности применения индикатора выполнения процесса по умолчанию и пошагового индикатора. Скопируйте этот код в свой редактор Python, сохраните его, а затем создайте для него инструмент-скрипт. У инструмента-скрипта будет два параметра с типом Long integer, как показано в комментариях к коду. Запустите инструмент-скрипт, применяя разные значения параметров (начните с n = 10 и p = 1, затем попробуйте n = 101 и p = 3).
'''
Demonstration script showing examples of using the progressor
Parameters:
n - number to count to (a good first choice is 10)
p - interval to count by (a good first choice is 1)
The various time.sleep() calls are just to slow the dialog down so you can view
messages and progressor labels.
'''
import arcpy
import time
n = arcpy.GetParameter(0)
p = arcpy.GetParameter(1)
readTime = 2.5 # Pause to read what's written on dialog
loopTime = 0.3 # Loop iteration delay
arcpy.AddMessage("Running demo with: {} by {}\n".format(n, p))
# Start by showing the default progress dialog, where the progress bar goes
# back and forth. Note how the progress label mimics working through some
# "phases", or chunks of work that a script may perform.
arcpy.SetProgressor("default", "This is the default progressor")
time.sleep(readTime)
for i in range(1, 4):
arcpy.SetProgressorLabel("Working on 'phase' {}".format(i))
arcpy.AddMessage("Messages for phase {}".format(i))
time.sleep(readTime)
# Setup the progressor with its initial label, min, max, and interval
arcpy.SetProgressor("step",
"Step progressor: Counting from 0 to {}".format(n),
0, n, p)
time.sleep(readTime)
# Loop issuing a new label when the increment is divisible by the value of
# countBy (p). The "%" is Python's modulus operator - we only update the
# position every p'th iteration.
for i in range(n):
if (i % p) == 0:
arcpy.SetProgressorLabel("Iteration: {}".format(i))
arcpy.SetProgressorPosition(i)
time.sleep(loopTime)
# Update the remainder that may be left over due to modulus operation.
arcpy.SetProgressorLabel("Iteration: {}".format(i + 1))
arcpy.SetProgressorPosition(i + 1)
arcpy.AddMessage("Done counting up\n")
time.sleep(readTime)
Выбор подходящего прироста, когда потенциал максимума велик
Совсем не редко пишутся скрипты, которые неизвестно сколько раз будут повторяться. Например, ваш скрипт может использовать arcpy.da.SearchCursor, выполнясь во всех строках таблицы, количество которых заранее вам не известно, и ваш скрипт может использоваться с таблицами любого размера, от нескольких тысяч строк до миллионов строк. Приращение пошагового прогрессора для каждой строки в большой таблице является узким местом производительности, и может потребоваться защита от таких узких мест.
Чтобы продемонстрировать и оценить проблемы с производительностью с помощью пошагового прогрессора, скопируйте нижеуказанный код в свой редактор Python, сохраните его, а затем создайте для него инструмент-скрипт. Этот инструмент имеет два входных параметра (inputs): параметр таблицы и параметр поля. Запустите скрипт-инструмент с таблицами разных размеров, но обязательно попробуйте таблицу или класс пространственных объектов, содержащий 10 000 или более строк, чтобы увидеть разницу в производительности.
Скрипт выполняет три отдельных цикла, и каждый цикл достигает все строки в таблице. Эти циклы отличаются с точки зрения того, как они обновляют шкалу хода выполнения. Первый и второй циклы обновляют шкалу ходя выполнения большими приростами, а последний цикл увеличивает эту шкалу один раз в каждой строке. Когда вы будете запускать этот инструмент, вы увидите, что для запуска этого последнего цикла требуется больше времени.
Вы можете использовать имеющуюся в данном коде технику для ваших собственных инструментов-скриптов.
'''
Demonstrates a step progressor by looping through records on a table. Use a
table with 10,000 or so rows - smaller tables will finish too quickly to assess.
1 = table name
2 = field on the table
'''
import arcpy
import time
import math
try:
inTable = arcpy.GetParameterAsText(0)
inField = arcpy.GetParameterAsText(1)
# Determine number of records in table
record_count = int(arcpy.management.GetCount(inTable)[0])
if record_count == 0:
raise ValueError("{} has no records to count".format(inTable))
arcpy.AddMessage("Number of rows = {}\n".format(record_count))
# Method 1: Calculate and use a suitable base 10 increment
# ========================================================
p = int(math.log10(record_count))
if not p:
p = 1
increment = int(math.pow(10, p - 1))
arcpy.SetProgressor(
"step", "Incrementing by {} on {}".format(increment, inTable),
0, record_count, increment)
beginTime = time.clock()
with arcpy.da.SearchCursor(inTable, [inField]) as cursor:
for i, row in enumerate(cursor, 0):
if (i % increment) == 0:
arcpy.SetProgressorPosition(i)
fieldValue = row[0]
arcpy.SetProgressorPosition(i)
arcpy.AddMessage("Method 1")
arcpy.AddMessage("\tIncrement = {}".format(increment))
arcpy.AddMessage("\tElapsed time: {}\n".format(time.clock() - beginTime))
# Method 2: let's just move in 10 percent increments
# ==================================================
increment = int(record_count / 10.0)
arcpy.SetProgressor(
"step", "Incrementing by {} on {}".format(increment, inTable),
0, record_count, increment)
beginTime = time.clock()
with arcpy.da.SearchCursor(inTable, [inField]) as cursor:
for i, row in enumerate(cursor, 0):
if (i % increment) == 0:
arcpy.SetProgressorPosition(i)
fieldValue = row[0]
arcpy.SetProgressorPosition(i)
arcpy.AddMessage("Method 2")
arcpy.AddMessage("\tIncrement = {}".format(increment))
arcpy.AddMessage("\tElapsed time: {}\n".format(time.clock() - beginTime))
# Method 3: use increment of 1
# ============================
increment = 1
arcpy.SetProgressor("step",
"Incrementing by 1 on {}".format(inTable),
0, record_count, increment)
beginTime = time.clock()
with arcpy.da.SearchCursor(inTable, [inField]) as cursor:
for row in cursor:
arcpy.SetProgressorPosition()
fieldValue = row[0]
arcpy.SetProgressorPosition(record_count)
arcpy.ResetProgressor()
arcpy.AddMessage("Method 3")
arcpy.AddMessage("\tIncrement = {}".format(increment))
arcpy.AddMessage("\tElapsed time: {}\n".format(time.clock() - beginTime))
arcpy.AddMessage("Pausing for a moment to allow viewing...")
time.sleep(2.0) # Allow viewing of the finished progressor
except Exception as e:
arcpy.AddError(e[0])