Разверните функцию python, чтобы вернуть еще одно значение

#python #function #return

Вопрос:

У меня есть этот скрипт для выполнения резервного копирования конфигурации с устройств juniper на основе ввода из Netbox. Я хотел бы немного расширить этот скрипт, чтобы получить версию прошивки с устройства juniper и обновить наш netbox, используя пользовательское поле.

 #!/usr/bin/python3  import sys,os,getopt from getpass import getpass from jnpr.junos import Device import jnpr.junos.facts from jnpr.junos.utils.config import Config from jnpr.junos.exception import * from lxml import etree from pprint import pprint import pynetbox import datetime  nb = pynetbox.api(url='https://netbox-test/', token='lt;censoredgt;') save_path = '/config-backups/'  def printProgress(logtype,hostname,message):  print("%s:%s:%s"%(logtype,hostname,message))  def GetConfig(my_hostname, my_username, my_password):  try:  printProgress("INFO",my_hostname,"Connecting to device")  dev=Device(host=my_hostname,user=my_username,password=my_password)  dev.open(auto_probe=10)  dev.timeout=10  printProgress("INFO",my_hostname,"Retrieving config")  config = dev.rpc.get_config(options={'database':'committed','format':'set'})  junos_version = dev.facts['version']  configbackup = (etree.tostring(config, encoding='unicode', pretty_print=True))  completefilename = os.path.join(save_path, my_hostname ".set.config")   outfile=open(completefilename, "w")  outfile.write(configbackup)  dev.close()  outfile.close()  return True,junos_version  except Exception as err:  printProgress("ERROR",my_hostname,"Encountered exception while backing up config")  printProgress("ERROR",my_hostname,str(err))  return False  def main(argv):  junos_password = ''  try:  opts, args = getopt.getopt(argv,"?u:p:",["username=","password"])  except getopt.GetoptError:  print ('configbackup_junos.py -u lt;usernamegt; [-p lt;junos admin passwordgt;]')  sys.exit(2)  for opt, arg in opts:  if opt == '-?':  print ('configbackup_junos.py -u lt;usernamegt; [-p lt;junos admin passwordgt;]')  sys.exit()  elif opt in ("-u", "--username"):  junos_username = arg  elif opt in ("-p", "--password"):  junos_password = arg  print ('Will attempt to backup junos devices documented in Netbox using username:', junos_username)  if len(junos_password) gt; 0:  print ('Junos Password set on commandlinen')  else:  print ('password not entered, will ask for it')  junos_password=getpass(prompt="nPassword: ")   nb_devicelist = nb.dcim.devices.all()  for nb_device in nb_devicelist:  platform = str(nb_device.platform)  pri_ip = str(nb_device.primary_ip)  asset = nb_device.asset_tag  devstatus = str(nb_device.status)  backup_enabled = nb_device.custom_fields['backup_enable']  if nb_device.virtual_chassis:  vchassismaster = str(nb_device.virtual_chassis.master)  else:  vchassismaster = 'no_chassis'  if backup_enabled == 'Yes' and platform == 'Junos' and devstatus == 'Active' and pri_ip != 'None' and asset:  if vchassismaster == (nb_device.name) or vchassismaster == 'no_chassis':  if GetConfig(asset,junos_username,junos_password):  print ("Config Successfully backed up from device.",nb_device)  nb_device.custom_fields['backup_status'] = "OK"  timenow = datetime.datetime.now()  timestamp = timenow.strftime("%Y-%m-d %X")  nb_device.custom_fields['backup_timestamp'] = timestamp  nb_device.save()  print (junos_version)  else:  printProgress ("ERROR",nb_device,"Config backup failed! ")  nb_device.custom_fields['backup_status'] = "FAILED"  nb_device.save()  print("")  if len(sys.argv) == 1:  sys.exit()   if __name__ == "__main__":  main(sys.argv[1:])  

Моя проблема в том, как мне получить переменную «junos_version», возвращаемую функцией getConfig. Как вы можете видеть,я пытался использовать «return True, junos_version», но как мне захватить его в выводе функции? (Я прочитал все статьи, которые смог найти об этом, и попробовал ряд предложений, но ничего не работает. Мне нужно иметь возможность ввести «junos_version» в эту команду nb_device.custom_fields['firmware_version'] = junos_version Который я бы разместил как раз перед nb_device.save

Я подозреваю, что здесь подводит мое чувство логики, я просто не вижу леса за деревьями.

Ответ №1:

if GetConfig(asset,junos_username,junos_password):

вы можете изменить это с помощью :

with flag, junos_version=GetConfig(asset,junos_username,junos_password):

Комментарии:

1. Это приведет к ошибке not enough values to unpack , если GetConfig перейдет к exception .

2. затем верните другое значение в части исключения, не желательно, чтобы функция иногда возвращала 1 значение, а иногда возвращала 2

Ответ №2:

Если вы возвращаете несколько значений из функции, считайте их кортежем. В вашем случае вы можете получить второе значение следующим образом:

 cfg = GetConfig(...) // add your args junos_version = cfg[1] // get the 2-nd returned value from a tuple.  

Ответ №3:

Сначала у вас должна быть стабильная доходность.

 def GetConfig(my_hostname, my_username, my_password):  try:  ...  return True,junos_version  except Exception as err:  ...  return False  

Здесь вы можете получить кортеж (логического значения и версии) или bool (True или False) в качестве возврата.

Я бы изменил его как:

 def GetConfig(my_hostname, my_username, my_password):  try:  ...  return True,junos_version  except Exception as err:  ...  return False, None  

так как нет никаких junos_version исключений.

Теперь вы меняете код, в котором используете его в качестве:

 def main(argv):  ...  if GetConfig(asset,junos_username,junos_password):  ...  

Для

 def main(argv):  ...  cfg, version = GetConfig(asset,junos_username,junos_password)  if cfg:  ...  

Комментарии:

1. Я выбрал это решение, потому что это очень хорошо объясненное решение, которое также сработало. 🙂