Python新手;拆分一个字符串

时间:2012-10-04 11:16:55

标签: python

我正在尝试为一些开源软件编写补丁,因为它不会完全我想要的东西 - 除了我根本不懂Python!我希望这很简单,但它正在打败我。

后台:我正在编写的补丁是用于管理KVM虚拟机群集的Ganeti,但它不支持KVM和Qemu的所有可能的命令行选项,例如USB传递,所以我试图修改它以允许这个。

kvm_cmd.extend()用于添加将在VM启动时传递的KVM CLI args数组。如果参数是空格分隔的,则每个参数变为单独的字符串,例如-usb -device usb-host,hostbus=1,hostdev=14变为"-usb", "-device", "usb-host,hostbus=1,hostdev=14"

我在编译代码后运行以下命令:

gnt-instance modify -H usb_pass="1;14"

我希望将其添加到现有的命令行参数列表"-usb -device usb-host,hostbus=1,hostdev=14"中。这是我添加的代码(以及在其他地方声明变量; HV_USBPASSTHROUGH是一个字符串,但这就是魔术发生的地方)

usb_pass = instance.hvparams[constants.HV_USBPASSTHROUGH]
if usb_pass:
    usb_pass_arr = []
    usb_pass_arr = usb_pass.split(";")
    kvm_cmd.extend(["-usb", "-device", "usb-host,hostbus=%s,hostaddr=%s" %
                    usb_pass_arr])

使用上面的代码运行上面的命令时出现以下错误:Could not start instance: Error while executing backend function: not enough arguments for format string

7 个答案:

答案 0 :(得分:7)

`%s中有两个"usb-host,hostbus=%s,hostaddr=%s",但只提供一个参数,一个列表,其中包含一个元组。

使用

"usb-host,hostbus=%s,hostaddr=%s" % tuple(usb_pass_arr)

tuple() builtin将迭代转换为元组。

答案 1 :(得分:3)

更改

"usb-host,hostbus=%s,hostaddr=%s" % usb_pass_arr

"usb-host,hostbus=%s,hostaddr=%s" % tuple(usb_pass_arr)

此外,usb_pass_arr不需要预先初始化,因为split()会返回一个新列表。

答案 2 :(得分:3)

你已经得到了"old" style formatting的答案;将new style formatting.format()一起使用,您可以使用variable-length argument syntax执行以下操作,自动将usb_pass解包为format()的函数参数:

'usb-host,hostbus={},hostaddr={}'.format(*usb_pass)

答案 3 :(得分:1)

您需要做的就是将usb_pass_arr作为元组传递,这是string formatting所期望的。

usb_pass = instance.hvparams[constants.HV_USBPASSTHROUGH]
if usb_pass:
    usb_pass_arr = [] #you can remove this line
    usb_pass_arr = tuple(usb_pass.split(";")) #a tuple is an immutable list
    kvm_cmd.extend(["-usb", "-device", "usb-host,hostbus=%s,hostaddr=%s" %
                    usb_pass_arr])

答案 4 :(得分:1)

正如人们已经写过的那样,您需要使用tuple(usb_pass_arr)将列表转换为元组。 请参阅python docs中的this段:

  

如果format需要单个参数,则值可以是单个非元组对象。否则,值必须是具有格式字符串指定的项目数的元组,或者是单个映射对象(例如,字典)。

答案 5 :(得分:0)

粗略猜测 - 您需要使用此代码:

"usb-host,hostbus=%s,hostaddr=%s" % (usb_pass_arr[0], usb_pass_arr[1])

答案 6 :(得分:0)

嗨大卫莫顿和其他任何感兴趣的人,这是Ganeti 2.6.0 USB传递每个实例的单个USB设备;

    diff -r -c ganeti-2.6.0_original/lib/constants.py ganeti-2.6.0_changed/lib/constants.py
*** ganeti-2.6.0_original/lib/constants.py  2012-07-27 12:31:48.000000000 +0100
--- ganeti-2.6.0_changed/lib/constants.py   2012-10-04 13:46:15.881572099 +0100
***************
*** 770,775 ****
--- 770,776 ----
  HV_KVM_USE_CHROOT = "use_chroot"
  HV_CPU_MASK = "cpu_mask"
  HV_MEM_PATH = "mem_path"
+ HV_USBPASSTHROUGH = "usb_pass"
  HV_BLOCKDEV_PREFIX = "blockdev_prefix"
  HV_REBOOT_BEHAVIOR = "reboot_behavior"

***************
*** 824,829 ****
--- 825,831 ----
    HV_KVM_USE_CHROOT: VTYPE_BOOL,
    HV_CPU_MASK: VTYPE_STRING,
    HV_MEM_PATH: VTYPE_STRING,
+   HV_USBPASSTHROUGH: VTYPE_STRING,
    HV_BLOCKDEV_PREFIX: VTYPE_STRING,
    HV_REBOOT_BEHAVIOR: VTYPE_STRING,
    }
***************
*** 1809,1814 ****
--- 1811,1817 ----
      HV_MEM_PATH: "",
      HV_REBOOT_BEHAVIOR: INSTANCE_REBOOT_ALLOWED,
      HV_CPU_MASK: CPU_PINNING_ALL,
+     HV_USBPASSTHROUGH: "",
      },
    HT_FAKE: {
      },
Only in ganeti-2.6.0_changed/lib/: .dir
Only in ganeti-2.6.0_changed/lib/: _generated_rpc.py
Only in ganeti-2.6.0_changed/lib/http: .dir
Only in ganeti-2.6.0_changed/lib/hypervisor: .dir
diff -r -c ganeti-2.6.0_original/lib/hypervisor/hv_kvm.py ganeti-2.6.0_changed/lib/hypervisor/hv_kvm.py
*** ganeti-2.6.0_original/lib/hypervisor/hv_kvm.py  2012-07-27 13:27:41.000000000 +0100
--- ganeti-2.6.0_changed/lib/hypervisor/hv_kvm.py   2012-10-04 13:46:54.993572107 +0100
***************
*** 490,495 ****
--- 490,496 ----
      constants.HV_VHOST_NET: hv_base.NO_CHECK,
      constants.HV_KVM_USE_CHROOT: hv_base.NO_CHECK,
      constants.HV_MEM_PATH: hv_base.OPT_DIR_CHECK,
+     constants.HV_USBPASSTHROUGH:  hv_base.NO_CHECK,
      constants.HV_REBOOT_BEHAVIOR:
        hv_base.ParamInSet(True, constants.REBOOT_BEHAVIORS),
      constants.HV_CPU_MASK: hv_base.OPT_MULTI_CPU_MASK_CHECK,
***************
*** 1257,1262 ****
--- 1258,1268 ----
      kvm_nics = instance.nics
      hvparams = hvp

+     usb_pass = instance.hvparams[constants.HV_USBPASSTHROUGH]
+     if usb_pass:
+         usb_pass_arr = usb_pass.split(";")
+         kvm_cmd.extend(["-usb", "-device", "usb-host,hostbus=%s,hostaddr=%s" % tuple(usb_pass_arr)])
+ 
      return (kvm_cmd, kvm_nics, hvparams)

    def _WriteKVMRuntime(self, instance_name, data):
Only in ganeti-2.6.0_changed/lib/impexpd: .dir
Only in ganeti-2.6.0_changed/lib/masterd: .dir
diff -r -c ganeti-2.6.0_original/lib/query.py ganeti-2.6.0_changed/lib/query.py
*** ganeti-2.6.0_original/lib/query.py  2012-07-27 12:31:48.000000000 +0100
--- ganeti-2.6.0_changed/lib/query.py   2012-10-04 13:46:26.625572103 +0100
***************
*** 1745,1750 ****
--- 1745,1751 ----
      constants.HV_NIC_TYPE: "NIC_type",
      constants.HV_PAE: "PAE",
      constants.HV_VNC_BIND_ADDRESS: "VNC_bind_address",
+     constants.HV_USBPASSTHROUGH: "usb_pass",
      }

    fields = [
Only in ganeti-2.6.0_changed/lib/rapi: .dir
Only in ganeti-2.6.0_changed/lib/server: .dir
Only in ganeti-2.6.0_changed/lib/tools: .dir
Only in ganeti-2.6.0_changed/lib/utils: .dir
Only in ganeti-2.6.0_changed/lib/: _vcsversion.py
Only in ganeti-2.6.0_changed/lib/watcher: .dir