Python 类型错误:强制转换为 Unicode:需要字符串或缓冲区,找到文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21126918/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
TypeError: coercing to Unicode: need string or buffer, file found
提问by insecure-IT
I'm getting a buffer error, but I have a line buffer in the 'with open()' block at line 123. Is this the correct location for the buffer? Should I have something in the connects class too/instead, or the parser argument maybe.
我收到缓冲区错误,但我在第 123 行的“with open()”块中有一个行缓冲区。这是缓冲区的正确位置吗?我是否也应该在connects 类中也有一些东西/代替,或者可能是解析器参数。
I'm trying to use a file with addresses or hostnames using a '--host_file' argument to run the SNMP commands on multiple ASA's. It works using the '--host' argument just fine.
我正在尝试使用带有“--host_file”参数的地址或主机名的文件在多个 ASA 上运行 SNMP 命令。它可以使用“--host”参数很好地工作。
Any help provided would be greatly appreceated.
提供的任何帮助将不胜感激。
Traceback (most recent call last):
File "asaos-snmpv3-tool.py", line 145, in <module>
main()
File "asaos-snmpv3-tool.py", line 124, in main
with open(hosts, mode='r', buffering=-1):
TypeError: coercing to Unicode: need string or buffer, file found
import pexpect
import argparse
PROMPT = ['# ', '>>> ', '>', '$ ']
SNMPGROUPCMD = ' snmp-server group '
V3PRIVCMD = ' v3 priv '
SNMPSRVUSRCMD = ' snmp-server user '
V3AUTHCMD = ' v3 auth '
PRIVCMD = ' priv '
SNMPSRVHOSTCMD = ' snmp-server host '
VERSION3CMD = ' version 3 '
SHAHMACCMD = ' sha '
SNMPSRVENTRAP = ' snmp-server enable traps all '
WRME = ' write memory '
def send_command(child, cmd):
child.sendline(cmd)
child.expect(PROMPT)
print child.before
def connect(user, host, passwd, en_passwd):
ssh_newkey = 'Are you sure you want to continue connecting?'
constr = 'ssh ' + user + '@' + host
child = pexpect.spawn(constr)
ret = child.expect([pexpect.TIMEOUT, ssh_newkey, '[P|p]assword:'])
if ret == 0:
print '[-] Error Connecting'
return
if ret == 1:
child.sendline('yes')
ret = child.expect([pexpect.TIMEOUT, '[P|p]assword:'])
if ret == 0:
print '[-] Error Connecting'
return
child.sendline(passwd)
child.expect(PROMPT)
child.sendline('enable')
child.sendline(en_passwd)
child.expect(PROMPT)
child.sendline('config t')
child.expect(PROMPT)
return child
def connects(user, hosts, passwd, en_passwd):
ssh_newkey = 'Are you sure you want to continue connecting?'
constr = 'ssh ' + user + '@' + hosts
child = pexpect.spawn(constr)
ret = child.expect([pexpect.TIMEOUT, ssh_newkey, '[P|p]assword:'])
if ret == 0:
print '[-] Error Connecting'
return
if ret == 1:
child.sendline('yes')
ret = child.expect([pexpect.TIMEOUT, '[P|p]assword:'])
if ret == 0:
print '[-] Error Connecting'
return
child.sendline(passwd)
child.expect(PROMPT)
child.sendline('enable')
child.sendline(en_passwd)
child.expect(PROMPT)
child.sendline('config t')
child.expect(PROMPT)
return child
def main():
parser = argparse.ArgumentParser('usage %prog ' + '--host --host_file --username --password--enable --group --snmp_user --snmp_host --int_name --snmp_v3_auth --snmp_v3_hmac --snmp_v3_priv --snmp_v3_encr')
parser.add_argument('--host', dest='host', type=str, help='specify a target host')
parser.add_argument('--host_file', dest='hosts', type=file, help='specify a target host file')
parser.add_argument('--username', dest='user', type=str, help='specify a user name')
parser.add_argument('--password', dest='passwd', type=str, help='specify a passwd')
parser.add_argument('--enable', dest='en_passwd', type=str, help='specify an enable passwd')
parser.add_argument('--group', dest='group', type=str, help='specify an snmp group')
parser.add_argument('--snmp_user', dest='snmpuser', type=str, help='specify an snmp user')
parser.add_argument('--snmp_host', dest='snmphost', type=str, help='specify an snmp server host')
parser.add_argument('--int_name', dest='intname', type=str, help='specify interface name')
parser.add_argument('--snmp_v3_auth', dest='snmpauth', type=str, help='specify the snmp user authentication')
parser.add_argument('--snmp_v3_hmac', dest='snmphmac', type=str, help='set snmp HMAC, md5 or sha')
parser.add_argument('--snmp_v3_priv', dest='snmppriv', type=str, help='specify the snmp priv password')
parser.add_argument('--snmp_v3_encr', dest='snmpencrypt', type=str, help='specify encryption, des, 3des, or aes(128/192/256)')
args = parser.parse_args()
host = args.host
hosts = args.hosts
user = args.user
passwd = args.passwd
en_passwd = args.en_passwd
group = args.group
snmpuser = args.snmpuser
snmphost = args.snmphost
intname = args.intname
snmpauth = args.snmpauth
snmppriv = args.snmppriv
snmpencrypt = args.snmpencrypt
if hosts:
with open(hosts, mode='r', buffering=1):
for line in hosts:
hosts = line.rstrip
child = connects(user, hosts, passwd, en_passwd)
send_command(child, SNMPGROUPCMD + group + V3PRIVCMD)
send_command(child, SNMPSRVUSRCMD + snmpuser + ' ' + group + V3AUTHCMD + SHAHMACCMD + snmpauth + PRIVCMD + snmpencrypt + ' ' + snmppriv)
send_command(child, SNMPSRVHOSTCMD + intname + ' ' + snmphost + VERSION3CMD + snmpuser)
send_command(child, SNMPSRVENTRAP)
send_command(child, WRME)
elif host:
child = connect(user, host, passwd, en_passwd)
send_command(child, SNMPGROUPCMD + group + V3PRIVCMD)
send_command(child, SNMPSRVUSRCMD + snmpuser + ' ' + group + V3AUTHCMD + SHAHMACCMD + snmpauth + PRIVCMD + snmpencrypt + ' ' + snmppriv)
send_command(child, SNMPSRVHOSTCMD + intname + ' ' + snmphost + VERSION3CMD + snmpuser)
send_command(child, SNMPSRVENTRAP)
send_command(child, WRME)
else:
print ('Specify either --host or --host_file or I have nothing to do')
if __name__ == '__main__':
main()
采纳答案by abarnert
There are a whole series of problems here:
这里有一系列的问题:
if hosts:
with open(hosts, mode='r', buffering=1):
Here, hostsis clearly meant to be a filename. You open that file…?and then don't store it in a variable anywhere, and go on to use the filename as if it were a file.
在这里,hosts显然是一个文件名。你打开那个文件……?然后不要把它存储在任何地方的变量中,继续使用文件名,就好像它是一个文件一样。
But, before you even get there, hostsis not actuallya filename. One of the nifty features of argparseis that it can automatically open files for you, and you're asking it to do that by using type=filein the argument spec. Which means that hostsis actually a file object, and you're trying to use that file object itself as a filename! Which is what' actually causing the TypeError: coercing to Unicode: need string or buffer, file found: opentries to convert filenames to Unicode strings, and it has no idea how to do that with a file object. If you want to openhosts, don't tell argparse to do it for you; just leave its type as a str.
但是,在你到达那里之前,hosts它实际上并不是一个文件名。的一个很好的特性argparse是它可以自动为你打开文件,你要求它通过type=file在参数规范中使用来做到这一点。这意味着它hosts实际上是一个文件对象,而您正试图将该文件对象本身用作文件名!这就是真正导致TypeError: coercing to Unicode: need string or buffer, file found:open尝试将文件名转换为 Unicode 字符串的原因,它不知道如何使用文件对象来做到这一点。如果你想open托管,不要告诉 argparse 为你做;只需将其类型保留为str.
for line in hosts:
Since hostsis supposed to be a filename, as a string, this will give you each character in the filename, as a string. Which is not useful.
由于hosts应该是一个文件名,作为一个字符串,这将为您提供文件名中的每个字符,作为一个字符串。这是没有用的。
hosts = line.rstrip
This overwrites the hostsvariable, which you need. And, even worse, it overwrites it with the bound method line.rstrip, rather than the result of calling line.rstrip.
这将覆盖hosts您需要的变量。而且,更糟糕的是,它用绑定的方法覆盖它line.rstrip,而不是调用的结果line.rstrip。
child = connects(user, hosts, passwd, en_passwd)
And here, you're passing that bound method to a function that wants a string, which isn't going to work.
在这里,您将该绑定方法传递给需要字符串的函数,但该函数将不起作用。
Don't keep using the same variable name over and over to mean different things. Use a different name for each thing. Ideally one whose name relates in some way to the thing it's holding. For example, a ech (stripped) line in a file named hostsis probably a host, or a hosts_entry… one thing it's notis all of your hosts.
不要一遍又一遍地使用相同的变量名来表示不同的东西。为每个事物使用不同的名称。理想情况下,它的名字在某种程度上与它所持有的东西有关。例如,名为的文件中的 ech(剥离)行hosts可能是 ahost或 a hosts_entry... 一件事不是您的hosts.
Anyway, to fix all of these problems:
无论如何,要解决所有这些问题:
if hosts:
for line in hosts:
host = line.rstrip()
child = connects(user, host, passwd, en_passwd)
Or, if you want to control how hostsis being opened (I'm not sure why you think it's important to specify buffering=1, but presumably you have some reason?):
或者,如果您想控制如何hosts打开(我不确定为什么您认为指定 很重要buffering=1,但大概您有一些原因?):
parser.add_argument('--host_file', dest='hosts', type=str, help='specify a target host file')
# …
if hosts:
with open(hosts, buffering=1) as hosts_file:
for line in hosts_file:
host = line.rstrip()
child = connects(user, host, passwd, en_passwd)
回答by mhlester
it lookslike you're iterating over the wrong thing here:
它看起来像你遍历此错误的事情:
with open(hosts, mode='r', buffering=1):
for line in hosts:
hosts = line.rstrip
You maybe want this:
你可能想要这个:
with open(hosts, mode='r', buffering=1) as lines:
for line in lines:
host = line.rstrip

