zeromq:TypeError:字符串索引必须是整数,而不是 str
Posted
技术标签:
【中文标题】zeromq:TypeError:字符串索引必须是整数,而不是 str【英文标题】:zeromq: TypeError: string indices must be integers, not str 【发布时间】:2014-10-13 03:30:54 【问题描述】:我想在机器之间建立发布订阅通信。
我拥有的两台机器是ryu-primary
和ryu-secondary
我在每台机器中遵循的步骤如下。
在ryu-primary
的初始化器中(IP地址是192.168.241.131)
self.context = zmq.Context()
self.sub_socket = self.context.socket(zmq.SUB)
self.pub_socket = self.context.socket(zmq.PUB)
self.pub_port = 5566
self.sub_port = 5566
def establish_zmq_connection(self): # Socket to talk to server
print( "Connection to ryu-secondary..." )
self.sub_socket.connect( "tcp://192.168.241.132:%s" % self.sub_port )
def listen_zmq_connection(self):
print( 'Listen to zmq connection' )
self.pub_socket.bind( "tcp://*:%s" % self.pub_port )
def recieve_messages(self):
while True:
try:
string = self.sub_socket.recv( flags=zmq.NOBLOCK )
print( 'flow mod messages recieved '.format(string) )
return string
except zmq.ZMQError:
break
def push_messages(self,msg):
self.pub_socket.send( "%s" % (msg) )
来自 ryu-secondary(IP 地址 - 192.168.241.132)
在初始化器中
self.context = zmq.Context()
self.sub_socket = self.context.socket(zmq.SUB)
self.pub_socket = self.context.socket(zmq.PUB)
self.pub_port = 5566
self.sub_port = 5566
def establish_zmq_connection(self): # Socket to talk to server
print( "Connection to ryu-secondary..." )
self.sub_socket.connect( "tcp://192.168.241.131:%s" % self.sub_port )
def listen_zmq_connection(self):
print( 'Listen to zmq connection' )
self.pub_socket.bind( "tcp://*:%s" % self.pub_port )
def recieve_messages(self):
while True:
try:
string = self.sub_socket.recv( flags=zmq.NOBLOCK )
print( 'flow mod messages recieved '.format(string) )
return string
except zmq.ZMQError:
break
def push_messages(self,msg):
print( 'pushing message to publish socket' )
self.pub_socket.send( "%s" % (msg) )
这些是我拥有的功能。
我打电话给ryu-secondary
:
establish_zmq_connections()
push_messages()
在ryu-primary
,当我打电话时
listen_zmq_connection()
recieve_messages()
在使用.setsockopt( zmq.SUBSCRIBE = '')
但是我尝试发送的消息属于以下类型。
msg = 'in_port':in_port,'dst':dst,'actions':actions
self.push_messages(msg)
但是另一方面(recieve_messages()
执行此操作时出现以下错误
flow_mod = recieve_messages()
flow_mod['in_port']
flow_mod['dst']
flow_mod['actions']
TypeError: string indices must be integers, not str
【问题讨论】:
@WarrenWeckesser - 我想访问该字典中包含的信息,即键 'in_port'、'dst' 和 'actions' 的值 【参考方案1】:msg
是一个 Python 字典,但您正在发送(和接收)格式化为字符串的消息。可能最简单的做法是将msg
序列化为 JSON 格式,将其作为字符串发送,然后将接收到的字符串再次加载回字典。然后,只有这样,您才能正确访问键和值。像这样的东西应该可以工作(确保你在上面某处import json
):
# on the sending end
msg = 'in_port':in_port,'dst':dst,'actions':actions
msg_string = json.dumps(msg)
self.push_messages(msg)
# on the receiving end
payload = receive_messages()
message = json.loads(payload)
您可以找到 json
模块 here(适用于 Python 2)和 here 适用于 Python 3 的完整文档。
【讨论】:
谢谢你的回复。你能解释一下怎么做吗。我对python不是很精通吗?【参考方案2】:ZeroMQ API 背景
ZeroMQ .send()
.recv()
方法对字符串进行操作。你向他们传递一个他们不知道如何处理的字典对象。将字典对象转换为 JSON 格式,作为针对这种情况的序列化示例,您的工作就完成了。
答案 = 得到 TypeError 的原因是什么?
正如所写,ZeroMQ 的 .send()
方法在发送它不理解的对象方面并不能做太多事情,并且 .recv() 部分仍然读取在 ZeroMQ 层上传递的任何内容。
因此,您的 flow_mod
变量正确地接收 string 作为函数 return string
指令中的 recieve_messages()
订单。
string = self.sub_socket.recv( flags=zmq.NOBLOCK )
只提供任何字符串,无论是空字符串还是从套接字另一侧接收的任何非零长度字符串。
最后:
flow_mod['in_port']
将在语法上崩溃(并且必须这样做),因为变量 flow_mod
的内容,在此之前分配和类型调整,没有类似字典的访问方法来处理这个语法类型。
因此必须在此处引发 TypeError: string indices must be integers, not str
异常。
Q.E.D.
对象的 JSON 序列化表示 - 编码和解码介绍:
>>> import json
>>> print json.__doc__
JSON (javascript Object Notation) <http://json.org> is a subset of
JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data
interchange format.
[json] exposes an API familiar to users of the standard library
[marshal] and [pickle] modules. It is the externally maintained
version of the [json] library contained in Python 2.6, but maintains
compatibility with Python 2.4 and Python 2.5 and (currently) has
significant performance advantages, even without using the optional C
extension for speedups.
Encoding basic Python object hierarchies::
>>> import json
>>> json.dumps(['foo', 'bar': ('baz', None, 1.0, 2)])
'["foo", "bar": ["baz", null, 1.0, 2]]'
>>> print json.dumps("\"foo\bar")
"\"foo\bar"
>>> print json.dumps(u'\u1234')
"\u1234"
>>> print json.dumps('\\')
"\\"
>>> print json.dumps("c": 0, "b": 0, "a": 0, sort_keys=True)
"a": 0, "b": 0, "c": 0
>>> from StringIO import StringIO
>>> io = StringIO()
>>> json.dump(['streaming API'], io)
>>> io.getvalue()
'["streaming API"]'
Compact encoding::
>>> import json
>>> json.dumps([1,2,3,'4': 5, '6': 7], sort_keys=True, separators=(',',':'))
'[1,2,3,"4":5,"6":7]'
Pretty printing::
>>> import json
>>> print json.dumps('4': 5, '6': 7, sort_keys=True,
... indent=4, separators=(',', ': '))
"4": 5,
"6": 7
Decoding JSON::
>>> import json
>>> obj = [u'foo', u'bar': [u'baz', None, 1.0, 2]]
>>> json.loads('["foo", "bar":["baz", null, 1.0, 2]]') == obj
True
>>> json.loads('"\\"foo\\bar"') == u'"foo\x08ar'
True
>>> from StringIO import StringIO
>>> io = StringIO('["streaming API"]')
>>> json.load(io)[0] == 'streaming API'
True
Specializing JSON object decoding::
>>> import json
>>> def as_complex(dct):
... if '__complex__' in dct:
... return complex(dct['real'], dct['imag'])
... return dct
...
>>> json.loads('"__complex__": true, "real": 1, "imag": 2',
... object_hook=as_complex)
(1+2j)
>>> from decimal import Decimal
>>> json.loads('1.1', parse_float=Decimal) == Decimal('1.1')
True
Specializing JSON object encoding::
>>> import json
>>> def encode_complex(obj):
... if isinstance(obj, complex):
... return [obj.real, obj.imag]
... raise TypeError(repr(o) + " is not JSON serializable")
...
>>> json.dumps(2 + 1j, default=encode_complex)
'[2.0, 1.0]'
>>> json.JSONEncoder(default=encode_complex).encode(2 + 1j)
'[2.0, 1.0]'
>>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j))
'[2.0, 1.0]'
【讨论】:
谢谢你的回复。你能解释一下怎么做吗。我对python不是很精通吗? 直接投反对票?告诉我为什么勇敢的匿名反对者,这是平庸的做法...... 我按下了对系统的反对票:(我已经恢复了它。一旦它起作用就会赞成:) @liv2hak 你的 -1/+1 没问题,但在你之前还有另一个反对票。以上是关于zeromq:TypeError:字符串索引必须是整数,而不是 str的主要内容,如果未能解决你的问题,请参考以下文章
读取 JSON 字符串 | TypeError:字符串索引必须是整数
Python:TypeError:字符串索引必须是整数[关闭]