我是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 . . .
答案 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
调用添加到已经是字符串的内容中,但是...它永远不会帮助任何事情,它只会让事情发生变化更难阅读,所以我把它们留在了原来的版本中。