获取TypeError:一元+的错误操作数类型:' str'当试图使用子进程时

时间:2018-06-04 18:22:39

标签: python

我是python的新手,所以如果我犯了任何愚蠢的错误,请原谅我。我一直试图弄清楚如何将命令传递给cmd.exe大约一个小时,并且每次都遇到错误。最近我收到了这个错误:TypeError:一元+的错误操作数类型:' str'。任何帮助将不胜感激,谢谢。

#defines a function to run BDP command with subprocess
def runcommand(command):
    """Runs command in cmd.exe"""
    import subprocess
    cmd = command
    returned_value = subprocess.call(cmd, shell=True)  
    # returns the exit code in unix
    print('returned value:', returned_value)

#defines a messagebox function to tell user what file to get
def messagebox(displayinfo):
    """Presents a messagebox telling the user to select a file"""
    from tkinter import messagebox
    messagebox.showinfo(message = displayinfo)

#Sets home to users home path eg C:/users/hsun2
from pathlib import Path
home = str(Path.home())
from tkinter import filedialog

#asks user for location of bfc file
messagebox('Select the bfc.nii.gz file')
bfcfile = filedialog.askopenfilename()
print(bfcfile)

#asks user for location of DTI.nii files
messagebox('Select your DTI.nii file')
dtinii = filedialog.askopenfilename()

#asks user for location of bval file
messagebox('Select bval file')
bvalfile = filedialog.askopenfilename()

#asks user for bvec file
messagebox('Select bvec file')
bvecfile = filedialog.askopenfilename()

output = r"'C:\Program Files\BrainSuite18a\bdp\bdp.exe' " + bfcfile 
+ " --FRT --FRACT --tensor --nii " + dtinii + " -g " + bvalfile 
+ " -b " + bvecfile

#print(output)

#runs bdp command with user input
#output = runcommand("'C:\Program Files\BrainSuite18a\bdp\bdp.exe' " + bfcfile +
#" --FRT --FRACT --tensor --nii " + dtinii + " -g " + bvalfile +
#" -b " + bvecfile)

返回

C:/Users/hsun2/Desktop/localBDP/MTS/testpy/MTS126028/BrainSuite/sagT1MPRAGE_we_normal.bfc.nii.gz
Traceback (most recent call last):
  File "bdpcommandtest.py", line 44, in <module>
    + " --FRT --FRACT --tensor --nii " + dtinii + " -g " + bvalfile
TypeError: bad operand type for unary +: 'str'


------------------
(program exited with code: 1)

Press any key to continue . . .

2 个答案:

答案 0 :(得分:0)

你的output声明应该在每一行的末尾都有行继续符\。您以前的代码不需要它,因为它括在括号中。确保\是行中最后一个可见字符,你实际做的是“转义”后面的换行符。拨打str()是不必要的。

output = r"'C:\Program Files\BrainSuite18a\bdp\bdp.exe' " + bfcfile \
+ " --FRT --FRACT --tensor --nii " + dtinii + " -g " + bvalfile \
+ " -b " + bvecfile

对于Windows路径,您应该使用原始字符串(即r"..")使用\(或使用\\或/)作为目录分隔符。在你的路径\b被转换为没有它的退格(\ x08)。

答案 1 :(得分:0)

您最初发布的代码是合法的,因为长字符串连接表达式位于括号内,并且括号自动允许您将表达式继续到下一行:

output = runcommand("'C:\Program Files\BrainSuite18a\bdp\bdp.exe' " + bfcfile +
" --FRT --FRACT --tensor --nii " + dtinii + " -g " + bvalfile +
" -b " + bvecfile)

但是,当您在括号外使用完全相同的表达式时,它不再有效:

command = "'C:\Program Files\BrainSuite18a\bdp\bdp.exe' " + bfcfile +
" --FRT --FRACT --tensor --nii " + dtinii + " -g " + bvalfile +
" -b " + bvecfile

...因为现在它是三个独立的表达式,每行一个。第一个引发SyntaxError,因为它以+结束而没有正确的参数。

如果您将挂起的+移到下一行,就像在最终发布的代码中一样:

command = "'C:\Program Files\BrainSuite18a\bdp\bdp.exe' " + bfcfile
+ " --FRT --FRACT --tensor --nii " + dtinii + " -g " + bvalfile
+ " -b " + bvecfile

...现在它在语法上有效,但是没有意义 - 第一行很好,但第二行试图将一元+运算符应用于字符串,因此得到{{1} }。

您可以通过将表达式放回括号内来解决此问题:

TypeError

...或者使用反斜杠延续:

command = ("'C:\Program Files\BrainSuite18a\bdp\bdp.exe' " + bfcfile
+ " --FRT --FRACT --tensor --nii " + dtinii + " -g " + bvalfile
+ " -b " + bvecfile)

虽然实际上,即使缩进对于表达式中的Python在语句中没有意义,但对于人类读者来说它是有意义的,所以你应该尝试使它更具可读性,可能是这样的:

command = "'C:\Program Files\BrainSuite18a\bdp\bdp.exe' " + bfcfile \
+ " --FRT --FRACT --tensor --nii " + dtinii + " -g " + bvalfile \
+ " -b " + bvecfile

但是,此处的真实修复程序应该首先不使用字符串连接。你在这里没有使用shell,事实上你正在与它作斗争,而不是完全成功。所以只需使用一个参数列表并且不要求shell,现在我们不必担心引用或间隔或正确连接字符串:

command = (
    "'C:\Program Files\BrainSuite18a\bdp\bdp.exe' " + bfcfile
    + " --FRT --FRACT --tensor --nii " + dtinii
    + " -g " + bvalfile
    + " -b " + bvecfile
)

现在,请在没有command = [ r"C:\Program Files\BrainSuite18a\bdp\bdp.exe", bfcfile, "--FRT", "--FRACT", "--tensor", "-nii", dtinii, "-g", bvalfile, "-b", bvecfile ] 的情况下调用它:

shell=True

作为附注,请注意我在程序路径之前添加了returned_value = subprocess.call(command) 。 Python字符串文字中的r并不代表反斜杠和字母b,它表示\b退格字符。在源代码中使用带有反斜杠的Windows路径名作为文字值时,请始终对其进行转义,或使用原始^H前缀。

另外,我不确定为什么你将代码中的r调用添加到已经是字符串的内容中,但是...它永远不会帮助任何事情,它只会让事情发生变化更难阅读,所以我把它们留在了原来的版本中。